OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/image/image.h" | 5 #include "ui/gfx/image/image.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/synchronization/lock.h" |
12 #include "third_party/skia/include/core/SkBitmap.h" | 13 #include "third_party/skia/include/core/SkBitmap.h" |
13 #include "ui/gfx/image/image_png_rep.h" | 14 #include "ui/gfx/image/image_png_rep.h" |
14 #include "ui/gfx/image/image_skia.h" | 15 #include "ui/gfx/image/image_skia.h" |
15 #include "ui/gfx/size.h" | 16 #include "ui/gfx/size.h" |
16 | 17 |
17 #if !defined(OS_IOS) | 18 #if !defined(OS_IOS) |
18 #include "ui/gfx/codec/png_codec.h" | 19 #include "ui/gfx/codec/png_codec.h" |
19 #endif | 20 #endif |
20 | 21 |
21 #if defined(OS_IOS) | 22 #if defined(OS_IOS) |
22 #include "base/mac/foundation_util.h" | 23 #include "base/mac/foundation_util.h" |
23 #include "ui/gfx/image/image_skia_util_ios.h" | 24 #include "ui/gfx/image/image_skia_util_ios.h" |
24 #elif defined(OS_MACOSX) | 25 #elif defined(OS_MACOSX) |
25 #include "base/mac/mac_util.h" | 26 #include "base/mac/mac_util.h" |
26 #include "ui/gfx/image/image_skia_util_mac.h" | 27 #include "ui/gfx/image/image_skia_util_mac.h" |
27 #endif | 28 #endif |
28 | 29 |
29 namespace gfx { | 30 namespace gfx { |
30 | 31 |
31 namespace internal { | 32 namespace internal { |
32 | 33 |
| 34 class ImageRep; |
| 35 |
| 36 typedef std::map<Image::RepresentationType, ImageRep*> RepresentationMap; |
| 37 |
33 #if defined(OS_IOS) | 38 #if defined(OS_IOS) |
34 scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage( | 39 scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage( |
35 UIImage* uiimage); | 40 UIImage* uiimage); |
36 // Caller takes ownership of the returned UIImage. | 41 // Caller takes ownership of the returned UIImage. |
37 UIImage* CreateUIImageFromPNG( | 42 UIImage* CreateUIImageFromPNG( |
38 const std::vector<gfx::ImagePNGRep>& image_png_reps); | 43 const std::vector<gfx::ImagePNGRep>& image_png_reps); |
39 gfx::Size UIImageSize(UIImage* image); | 44 gfx::Size UIImageSize(UIImage* image); |
40 #elif defined(OS_MACOSX) | 45 #elif defined(OS_MACOSX) |
41 scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromNSImage( | 46 scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromNSImage( |
42 NSImage* nsimage); | 47 NSImage* nsimage); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 private: | 299 private: |
295 NSImage* image_; | 300 NSImage* image_; |
296 | 301 |
297 DISALLOW_COPY_AND_ASSIGN(ImageRepCocoa); | 302 DISALLOW_COPY_AND_ASSIGN(ImageRepCocoa); |
298 }; | 303 }; |
299 #endif // defined(OS_MACOSX) | 304 #endif // defined(OS_MACOSX) |
300 | 305 |
301 // The Storage class acts similarly to the pixels in a SkBitmap: the Image | 306 // The Storage class acts similarly to the pixels in a SkBitmap: the Image |
302 // class holds a refptr instance of Storage, which in turn holds all the | 307 // class holds a refptr instance of Storage, which in turn holds all the |
303 // ImageReps. This way, the Image can be cheaply copied. | 308 // ImageReps. This way, the Image can be cheaply copied. |
304 class ImageStorage : public base::RefCounted<ImageStorage> { | 309 class ImageStorage : public base::RefCountedThreadSafe<ImageStorage> { |
305 public: | 310 public: |
306 ImageStorage(gfx::Image::RepresentationType default_type) | 311 ImageStorage(gfx::Image::RepresentationType default_type) |
307 : default_representation_type_(default_type), | 312 : default_representation_type_(default_type), |
308 #if defined(OS_MACOSX) && !defined(OS_IOS) | 313 #if defined(OS_MACOSX) && !defined(OS_IOS) |
309 default_representation_color_space_( | 314 default_representation_color_space_( |
310 base::mac::GetGenericRGBColorSpace()), | 315 base::mac::GetGenericRGBColorSpace()), |
311 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 316 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
312 representations_deleter_(&representations_) { | 317 representations_deleter_(&representations_) { |
313 } | 318 } |
314 | 319 |
315 gfx::Image::RepresentationType default_representation_type() { | 320 gfx::Image::RepresentationType default_representation_type() const { |
316 return default_representation_type_; | 321 return default_representation_type_; |
317 } | 322 } |
318 gfx::Image::RepresentationMap& representations() { return representations_; } | 323 |
| 324 size_t representation_count() const { |
| 325 base::AutoLock lock(mutex_); |
| 326 return representations_.size(); |
| 327 } |
| 328 |
| 329 void add_representation(internal::ImageRep* rep) { |
| 330 base::AutoLock lock(mutex_); |
| 331 representations_.insert(std::make_pair(rep->type(), rep)); |
| 332 } |
| 333 |
| 334 bool has_representation(Image::RepresentationType type) const { |
| 335 base::AutoLock lock(mutex_); |
| 336 return representations_.count(type) != 0; |
| 337 } |
| 338 |
| 339 internal::ImageRep* get_representation( |
| 340 Image::RepresentationType rep_type) const { |
| 341 base::AutoLock lock(mutex_); |
| 342 internal::RepresentationMap::const_iterator it = |
| 343 representations_.find(rep_type); |
| 344 if (it == representations_.end()) |
| 345 return NULL; |
| 346 return it->second; |
| 347 } |
319 | 348 |
320 #if defined(OS_MACOSX) && !defined(OS_IOS) | 349 #if defined(OS_MACOSX) && !defined(OS_IOS) |
321 void set_default_representation_color_space(CGColorSpaceRef color_space) { | 350 void set_default_representation_color_space(CGColorSpaceRef color_space) { |
| 351 base::AutoLock lock(mutex_); |
322 default_representation_color_space_ = color_space; | 352 default_representation_color_space_ = color_space; |
323 } | 353 } |
324 CGColorSpaceRef default_representation_color_space() { | 354 CGColorSpaceRef default_representation_color_space() const { |
| 355 base::AutoLock lock(mutex_); |
325 return default_representation_color_space_; | 356 return default_representation_color_space_; |
326 } | 357 } |
327 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 358 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
328 | 359 |
329 private: | 360 private: |
330 friend class base::RefCounted<ImageStorage>; | 361 friend class base::RefCountedThreadSafe<ImageStorage>; |
331 | 362 |
332 ~ImageStorage() {} | 363 ~ImageStorage() {} |
333 | 364 |
334 // The type of image that was passed to the constructor. This key will always | 365 // The type of image that was passed to the constructor. This key will always |
335 // exist in the |representations_| map. | 366 // exist in the |representations_| map. |
336 gfx::Image::RepresentationType default_representation_type_; | 367 gfx::Image::RepresentationType default_representation_type_; |
337 | 368 |
338 #if defined(OS_MACOSX) && !defined(OS_IOS) | 369 #if defined(OS_MACOSX) && !defined(OS_IOS) |
339 // The default representation's colorspace. This is used for converting to | 370 // The default representation's colorspace. This is used for converting to |
340 // NSImage. This field exists to compensate for PNGCodec not writing or | 371 // NSImage. This field exists to compensate for PNGCodec not writing or |
341 // reading colorspace ancillary chunks. (sRGB, iCCP). | 372 // reading colorspace ancillary chunks. (sRGB, iCCP). |
342 // Not owned. | 373 // Not owned. |
| 374 // Must hold |mutex_| when accessing. |
343 CGColorSpaceRef default_representation_color_space_; | 375 CGColorSpaceRef default_representation_color_space_; |
344 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 376 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
345 | 377 |
346 // All the representations of an Image. Size will always be at least one, with | 378 // All the representations of an Image. Size will always be at least one, with |
347 // more for any converted representations. | 379 // more for any converted representations. |
348 gfx::Image::RepresentationMap representations_; | 380 // Must hold |mutex_| when accessing. |
| 381 RepresentationMap representations_; |
349 | 382 |
350 STLValueDeleter<Image::RepresentationMap> representations_deleter_; | 383 STLValueDeleter<RepresentationMap> representations_deleter_; |
| 384 |
| 385 // Lock for mutable fields of this object. |
| 386 mutable base::Lock mutex_; |
351 | 387 |
352 DISALLOW_COPY_AND_ASSIGN(ImageStorage); | 388 DISALLOW_COPY_AND_ASSIGN(ImageStorage); |
353 }; | 389 }; |
354 | 390 |
355 } // namespace internal | 391 } // namespace internal |
356 | 392 |
357 Image::Image() { | 393 Image::Image() { |
358 // |storage_| is NULL for empty Images. | 394 // |storage_| is NULL for empty Images. |
359 } | 395 } |
360 | 396 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 } | 681 } |
646 #elif defined(OS_MACOSX) | 682 #elif defined(OS_MACOSX) |
647 NSImage* Image::CopyNSImage() const { | 683 NSImage* Image::CopyNSImage() const { |
648 NSImage* image = ToNSImage(); | 684 NSImage* image = ToNSImage(); |
649 base::mac::NSObjectRetain(image); | 685 base::mac::NSObjectRetain(image); |
650 return image; | 686 return image; |
651 } | 687 } |
652 #endif | 688 #endif |
653 | 689 |
654 bool Image::HasRepresentation(RepresentationType type) const { | 690 bool Image::HasRepresentation(RepresentationType type) const { |
655 return storage_.get() && storage_->representations().count(type) != 0; | 691 return storage_.get() && storage_->has_representation(type); |
656 } | 692 } |
657 | 693 |
658 size_t Image::RepresentationCount() const { | 694 size_t Image::RepresentationCount() const { |
659 if (!storage_.get()) | 695 if (!storage_.get()) |
660 return 0; | 696 return 0; |
661 | 697 |
662 return storage_->representations().size(); | 698 return storage_->representation_count(); |
663 } | 699 } |
664 | 700 |
665 bool Image::IsEmpty() const { | 701 bool Image::IsEmpty() const { |
666 return RepresentationCount() == 0; | 702 return RepresentationCount() == 0; |
667 } | 703 } |
668 | 704 |
669 int Image::Width() const { | 705 int Image::Width() const { |
670 if (IsEmpty()) | 706 if (IsEmpty()) |
671 return 0; | 707 return 0; |
672 return GetRepresentation(DefaultRepresentationType(), true)->Width(); | 708 return GetRepresentation(DefaultRepresentationType(), true)->Width(); |
(...skipping 27 matching lines...) Expand all Loading... |
700 RepresentationType default_type = storage_->default_representation_type(); | 736 RepresentationType default_type = storage_->default_representation_type(); |
701 // The conversions above assume that the default representation type is never | 737 // The conversions above assume that the default representation type is never |
702 // kImageRepCairo. | 738 // kImageRepCairo. |
703 DCHECK_NE(default_type, kImageRepCairo); | 739 DCHECK_NE(default_type, kImageRepCairo); |
704 return default_type; | 740 return default_type; |
705 } | 741 } |
706 | 742 |
707 internal::ImageRep* Image::GetRepresentation( | 743 internal::ImageRep* Image::GetRepresentation( |
708 RepresentationType rep_type, bool must_exist) const { | 744 RepresentationType rep_type, bool must_exist) const { |
709 CHECK(storage_.get()); | 745 CHECK(storage_.get()); |
710 RepresentationMap::iterator it = storage_->representations().find(rep_type); | 746 internal::ImageRep* representation = storage_->get_representation(rep_type); |
711 if (it == storage_->representations().end()) { | 747 if (must_exist) |
712 CHECK(!must_exist); | 748 CHECK(representation); |
713 return NULL; | 749 return representation; |
714 } | |
715 return it->second; | |
716 } | 750 } |
717 | 751 |
718 void Image::AddRepresentation(internal::ImageRep* rep) const { | 752 void Image::AddRepresentation(internal::ImageRep* rep) const { |
719 CHECK(storage_.get()); | 753 CHECK(storage_.get()); |
720 storage_->representations().insert(std::make_pair(rep->type(), rep)); | 754 storage_->add_representation(rep); |
721 } | 755 } |
722 | 756 |
723 } // namespace gfx | 757 } // namespace gfx |
OLD | NEW |