| Index: ui/gfx/image/image.cc | 
| diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc | 
| index 0a5564d8d6c023597386e0f2e614e6cca779b6e1..a072ab09328c51c304ba786203a05b7c91ed6490 100644 | 
| --- a/ui/gfx/image/image.cc | 
| +++ b/ui/gfx/image/image.cc | 
| @@ -9,6 +9,7 @@ | 
| #include "base/logging.h" | 
| #include "base/memory/scoped_ptr.h" | 
| #include "base/stl_util.h" | 
| +#include "base/synchronization/lock.h" | 
| #include "third_party/skia/include/core/SkBitmap.h" | 
| #include "ui/gfx/image/image_png_rep.h" | 
| #include "ui/gfx/image/image_skia.h" | 
| @@ -30,6 +31,10 @@ namespace gfx { | 
|  | 
| namespace internal { | 
|  | 
| +class ImageRep; | 
| + | 
| +typedef std::map<Image::RepresentationType, ImageRep*> RepresentationMap; | 
| + | 
| #if defined(OS_IOS) | 
| scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage( | 
| UIImage* uiimage); | 
| @@ -301,7 +306,7 @@ class ImageRepCocoa : public ImageRep { | 
| // The Storage class acts similarly to the pixels in a SkBitmap: the Image | 
| // class holds a refptr instance of Storage, which in turn holds all the | 
| // ImageReps. This way, the Image can be cheaply copied. | 
| -class ImageStorage : public base::RefCounted<ImageStorage> { | 
| +class ImageStorage : public base::RefCountedThreadSafe<ImageStorage> { | 
| public: | 
| ImageStorage(gfx::Image::RepresentationType default_type) | 
| : default_representation_type_(default_type), | 
| @@ -312,22 +317,48 @@ class ImageStorage : public base::RefCounted<ImageStorage> { | 
| representations_deleter_(&representations_) { | 
| } | 
|  | 
| -  gfx::Image::RepresentationType default_representation_type() { | 
| +  gfx::Image::RepresentationType default_representation_type() const { | 
| return default_representation_type_; | 
| } | 
| -  gfx::Image::RepresentationMap& representations() { return representations_; } | 
| + | 
| +  size_t representation_count() const { | 
| +    base::AutoLock lock(mutex_); | 
| +    return representations_.size(); | 
| +  } | 
| + | 
| +  void add_representation(internal::ImageRep* rep) { | 
| +    base::AutoLock lock(mutex_); | 
| +    representations_.insert(std::make_pair(rep->type(), rep)); | 
| +  } | 
| + | 
| +  bool has_representation(Image::RepresentationType type) const { | 
| +    base::AutoLock lock(mutex_); | 
| +    return representations_.count(type) != 0; | 
| +  } | 
| + | 
| +  internal::ImageRep* get_representation( | 
| +      Image::RepresentationType rep_type) const { | 
| +    base::AutoLock lock(mutex_); | 
| +    internal::RepresentationMap::const_iterator it = | 
| +        representations_.find(rep_type); | 
| +    if (it == representations_.end()) | 
| +      return NULL; | 
| +    return it->second; | 
| +  } | 
|  | 
| #if defined(OS_MACOSX) && !defined(OS_IOS) | 
| void set_default_representation_color_space(CGColorSpaceRef color_space) { | 
| +    base::AutoLock lock(mutex_); | 
| default_representation_color_space_ = color_space; | 
| } | 
| -  CGColorSpaceRef default_representation_color_space() { | 
| +  CGColorSpaceRef default_representation_color_space() const { | 
| +    base::AutoLock lock(mutex_); | 
| return default_representation_color_space_; | 
| } | 
| #endif  // defined(OS_MACOSX) && !defined(OS_IOS) | 
|  | 
| private: | 
| -  friend class base::RefCounted<ImageStorage>; | 
| +  friend class base::RefCountedThreadSafe<ImageStorage>; | 
|  | 
| ~ImageStorage() {} | 
|  | 
| @@ -340,14 +371,19 @@ class ImageStorage : public base::RefCounted<ImageStorage> { | 
| // NSImage. This field exists to compensate for PNGCodec not writing or | 
| // reading colorspace ancillary chunks. (sRGB, iCCP). | 
| // Not owned. | 
| +  // Must hold |mutex_| when accessing. | 
| CGColorSpaceRef default_representation_color_space_; | 
| #endif  // defined(OS_MACOSX) && !defined(OS_IOS) | 
|  | 
| // All the representations of an Image. Size will always be at least one, with | 
| // more for any converted representations. | 
| -  gfx::Image::RepresentationMap representations_; | 
| +  // Must hold |mutex_| when accessing. | 
| +  RepresentationMap representations_; | 
|  | 
| -  STLValueDeleter<Image::RepresentationMap> representations_deleter_; | 
| +  STLValueDeleter<RepresentationMap> representations_deleter_; | 
| + | 
| +  // Lock for mutable fields of this object. | 
| +  mutable base::Lock mutex_; | 
|  | 
| DISALLOW_COPY_AND_ASSIGN(ImageStorage); | 
| }; | 
| @@ -652,14 +688,14 @@ NSImage* Image::CopyNSImage() const { | 
| #endif | 
|  | 
| bool Image::HasRepresentation(RepresentationType type) const { | 
| -  return storage_.get() && storage_->representations().count(type) != 0; | 
| +  return storage_.get() && storage_->has_representation(type); | 
| } | 
|  | 
| size_t Image::RepresentationCount() const { | 
| if (!storage_.get()) | 
| return 0; | 
|  | 
| -  return storage_->representations().size(); | 
| +  return storage_->representation_count(); | 
| } | 
|  | 
| bool Image::IsEmpty() const { | 
| @@ -707,17 +743,15 @@ Image::RepresentationType Image::DefaultRepresentationType() const { | 
| internal::ImageRep* Image::GetRepresentation( | 
| RepresentationType rep_type, bool must_exist) const { | 
| CHECK(storage_.get()); | 
| -  RepresentationMap::iterator it = storage_->representations().find(rep_type); | 
| -  if (it == storage_->representations().end()) { | 
| -    CHECK(!must_exist); | 
| -    return NULL; | 
| -  } | 
| -  return it->second; | 
| +  internal::ImageRep* representation = storage_->get_representation(rep_type); | 
| +  if (must_exist) | 
| +    CHECK(representation); | 
| +  return representation; | 
| } | 
|  | 
| void Image::AddRepresentation(internal::ImageRep* rep) const { | 
| CHECK(storage_.get()); | 
| -  storage_->representations().insert(std::make_pair(rep->type(), rep)); | 
| +  storage_->add_representation(rep); | 
| } | 
|  | 
| }  // namespace gfx | 
|  |