| 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 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/memory/ptr_util.h" |
| 13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 14 #include "third_party/skia/include/core/SkBitmap.h" | 15 #include "third_party/skia/include/core/SkBitmap.h" |
| 15 #include "ui/gfx/geometry/size.h" | 16 #include "ui/gfx/geometry/size.h" |
| 16 #include "ui/gfx/image/image_png_rep.h" | 17 #include "ui/gfx/image/image_png_rep.h" |
| 17 #include "ui/gfx/image/image_skia.h" | 18 #include "ui/gfx/image/image_skia.h" |
| 18 #include "ui/gfx/image/image_skia_source.h" | 19 #include "ui/gfx/image/image_skia_source.h" |
| 19 | 20 |
| 20 #if !defined(OS_IOS) | 21 #if !defined(OS_IOS) |
| 21 #include "ui/gfx/codec/png_codec.h" | 22 #include "ui/gfx/codec/png_codec.h" |
| 22 #endif | 23 #endif |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 ImageSkiaRepSet image_skia_reps_; | 130 ImageSkiaRepSet image_skia_reps_; |
| 130 gfx::Size size_; | 131 gfx::Size size_; |
| 131 | 132 |
| 132 DISALLOW_COPY_AND_ASSIGN(PNGImageSource); | 133 DISALLOW_COPY_AND_ASSIGN(PNGImageSource); |
| 133 }; | 134 }; |
| 134 | 135 |
| 135 ImageSkia* ImageSkiaFromPNG( | 136 ImageSkia* ImageSkiaFromPNG( |
| 136 const std::vector<ImagePNGRep>& image_png_reps) { | 137 const std::vector<ImagePNGRep>& image_png_reps) { |
| 137 if (image_png_reps.empty()) | 138 if (image_png_reps.empty()) |
| 138 return GetErrorImageSkia(); | 139 return GetErrorImageSkia(); |
| 139 scoped_ptr<PNGImageSource> image_source(new PNGImageSource); | 140 std::unique_ptr<PNGImageSource> image_source(new PNGImageSource); |
| 140 | 141 |
| 141 for (size_t i = 0; i < image_png_reps.size(); ++i) { | 142 for (size_t i = 0; i < image_png_reps.size(); ++i) { |
| 142 if (!image_source->AddPNGData(image_png_reps[i])) | 143 if (!image_source->AddPNGData(image_png_reps[i])) |
| 143 return GetErrorImageSkia(); | 144 return GetErrorImageSkia(); |
| 144 } | 145 } |
| 145 const gfx::Size& size = image_source->size(); | 146 const gfx::Size& size = image_source->size(); |
| 146 DCHECK(!size.IsEmpty()); | 147 DCHECK(!size.IsEmpty()); |
| 147 if (size.IsEmpty()) | 148 if (size.IsEmpty()) |
| 148 return GetErrorImageSkia(); | 149 return GetErrorImageSkia(); |
| 149 return new ImageSkia(image_source.release(), size); | 150 return new ImageSkia(image_source.release(), size); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 245 |
| 245 return *size_cache_; | 246 return *size_cache_; |
| 246 } | 247 } |
| 247 | 248 |
| 248 const std::vector<ImagePNGRep>& image_reps() const { return image_png_reps_; } | 249 const std::vector<ImagePNGRep>& image_reps() const { return image_png_reps_; } |
| 249 | 250 |
| 250 private: | 251 private: |
| 251 std::vector<ImagePNGRep> image_png_reps_; | 252 std::vector<ImagePNGRep> image_png_reps_; |
| 252 | 253 |
| 253 // Cached to avoid having to parse the raw data multiple times. | 254 // Cached to avoid having to parse the raw data multiple times. |
| 254 mutable scoped_ptr<gfx::Size> size_cache_; | 255 mutable std::unique_ptr<gfx::Size> size_cache_; |
| 255 | 256 |
| 256 DISALLOW_COPY_AND_ASSIGN(ImageRepPNG); | 257 DISALLOW_COPY_AND_ASSIGN(ImageRepPNG); |
| 257 }; | 258 }; |
| 258 | 259 |
| 259 class ImageRepSkia : public ImageRep { | 260 class ImageRepSkia : public ImageRep { |
| 260 public: | 261 public: |
| 261 // Takes ownership of |image|. | 262 // Takes ownership of |image|. |
| 262 explicit ImageRepSkia(ImageSkia* image) | 263 explicit ImageRepSkia(ImageSkia* image) |
| 263 : ImageRep(Image::kImageRepSkia), | 264 : ImageRep(Image::kImageRepSkia), |
| 264 image_(image) { | 265 image_(image) { |
| 265 } | 266 } |
| 266 | 267 |
| 267 ~ImageRepSkia() override {} | 268 ~ImageRepSkia() override {} |
| 268 | 269 |
| 269 int Width() const override { return image_->width(); } | 270 int Width() const override { return image_->width(); } |
| 270 | 271 |
| 271 int Height() const override { return image_->height(); } | 272 int Height() const override { return image_->height(); } |
| 272 | 273 |
| 273 gfx::Size Size() const override { return image_->size(); } | 274 gfx::Size Size() const override { return image_->size(); } |
| 274 | 275 |
| 275 ImageSkia* image() { return image_.get(); } | 276 ImageSkia* image() { return image_.get(); } |
| 276 | 277 |
| 277 private: | 278 private: |
| 278 scoped_ptr<ImageSkia> image_; | 279 std::unique_ptr<ImageSkia> image_; |
| 279 | 280 |
| 280 DISALLOW_COPY_AND_ASSIGN(ImageRepSkia); | 281 DISALLOW_COPY_AND_ASSIGN(ImageRepSkia); |
| 281 }; | 282 }; |
| 282 | 283 |
| 283 #if defined(OS_IOS) | 284 #if defined(OS_IOS) |
| 284 class ImageRepCocoaTouch : public ImageRep { | 285 class ImageRepCocoaTouch : public ImageRep { |
| 285 public: | 286 public: |
| 286 explicit ImageRepCocoaTouch(UIImage* image) | 287 explicit ImageRepCocoaTouch(UIImage* image) |
| 287 : ImageRep(Image::kImageRepCocoaTouch), | 288 : ImageRep(Image::kImageRepCocoaTouch), |
| 288 image_(image) { | 289 image_(image) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 std::vector<ImagePNGRep> filtered; | 401 std::vector<ImagePNGRep> filtered; |
| 401 for (size_t i = 0; i < image_reps.size(); ++i) { | 402 for (size_t i = 0; i < image_reps.size(); ++i) { |
| 402 if (image_reps[i].raw_data.get() && image_reps[i].raw_data->size()) | 403 if (image_reps[i].raw_data.get() && image_reps[i].raw_data->size()) |
| 403 filtered.push_back(image_reps[i]); | 404 filtered.push_back(image_reps[i]); |
| 404 } | 405 } |
| 405 | 406 |
| 406 if (filtered.empty()) | 407 if (filtered.empty()) |
| 407 return; | 408 return; |
| 408 | 409 |
| 409 storage_ = new internal::ImageStorage(Image::kImageRepPNG); | 410 storage_ = new internal::ImageStorage(Image::kImageRepPNG); |
| 410 AddRepresentation(make_scoped_ptr(new internal::ImageRepPNG(filtered))); | 411 AddRepresentation(base::WrapUnique(new internal::ImageRepPNG(filtered))); |
| 411 } | 412 } |
| 412 | 413 |
| 413 Image::Image(const ImageSkia& image) { | 414 Image::Image(const ImageSkia& image) { |
| 414 if (!image.isNull()) { | 415 if (!image.isNull()) { |
| 415 storage_ = new internal::ImageStorage(Image::kImageRepSkia); | 416 storage_ = new internal::ImageStorage(Image::kImageRepSkia); |
| 416 AddRepresentation( | 417 AddRepresentation( |
| 417 make_scoped_ptr(new internal::ImageRepSkia(new ImageSkia(image)))); | 418 base::WrapUnique(new internal::ImageRepSkia(new ImageSkia(image)))); |
| 418 } | 419 } |
| 419 } | 420 } |
| 420 | 421 |
| 421 #if defined(OS_IOS) | 422 #if defined(OS_IOS) |
| 422 Image::Image(UIImage* image) | 423 Image::Image(UIImage* image) |
| 423 : storage_(new internal::ImageStorage(Image::kImageRepCocoaTouch)) { | 424 : storage_(new internal::ImageStorage(Image::kImageRepCocoaTouch)) { |
| 424 if (image) | 425 if (image) |
| 425 AddRepresentation(make_scoped_ptr(new internal::ImageRepCocoaTouch(image))); | 426 AddRepresentation( |
| 427 base::WrapUnique(new internal::ImageRepCocoaTouch(image))); |
| 426 } | 428 } |
| 427 #elif defined(OS_MACOSX) | 429 #elif defined(OS_MACOSX) |
| 428 Image::Image(NSImage* image) { | 430 Image::Image(NSImage* image) { |
| 429 if (image) { | 431 if (image) { |
| 430 storage_ = new internal::ImageStorage(Image::kImageRepCocoa); | 432 storage_ = new internal::ImageStorage(Image::kImageRepCocoa); |
| 431 AddRepresentation(make_scoped_ptr(new internal::ImageRepCocoa(image))); | 433 AddRepresentation(base::WrapUnique(new internal::ImageRepCocoa(image))); |
| 432 } | 434 } |
| 433 } | 435 } |
| 434 #endif | 436 #endif |
| 435 | 437 |
| 436 Image::Image(const Image& other) : storage_(other.storage_) { | 438 Image::Image(const Image& other) : storage_(other.storage_) { |
| 437 } | 439 } |
| 438 | 440 |
| 439 Image& Image::operator=(const Image& other) { | 441 Image& Image::operator=(const Image& other) { |
| 440 storage_ = other.storage_; | 442 storage_ = other.storage_; |
| 441 return *this; | 443 return *this; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 472 } | 474 } |
| 473 | 475 |
| 474 const SkBitmap* Image::ToSkBitmap() const { | 476 const SkBitmap* Image::ToSkBitmap() const { |
| 475 // Possibly create and cache an intermediate ImageRepSkia. | 477 // Possibly create and cache an intermediate ImageRepSkia. |
| 476 return ToImageSkia()->bitmap(); | 478 return ToImageSkia()->bitmap(); |
| 477 } | 479 } |
| 478 | 480 |
| 479 const ImageSkia* Image::ToImageSkia() const { | 481 const ImageSkia* Image::ToImageSkia() const { |
| 480 internal::ImageRep* rep = GetRepresentation(kImageRepSkia, false); | 482 internal::ImageRep* rep = GetRepresentation(kImageRepSkia, false); |
| 481 if (!rep) { | 483 if (!rep) { |
| 482 scoped_ptr<internal::ImageRep> scoped_rep; | 484 std::unique_ptr<internal::ImageRep> scoped_rep; |
| 483 switch (DefaultRepresentationType()) { | 485 switch (DefaultRepresentationType()) { |
| 484 case kImageRepPNG: { | 486 case kImageRepPNG: { |
| 485 internal::ImageRepPNG* png_rep = | 487 internal::ImageRepPNG* png_rep = |
| 486 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); | 488 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); |
| 487 scoped_rep.reset(new internal::ImageRepSkia( | 489 scoped_rep.reset(new internal::ImageRepSkia( |
| 488 internal::ImageSkiaFromPNG(png_rep->image_reps()))); | 490 internal::ImageSkiaFromPNG(png_rep->image_reps()))); |
| 489 break; | 491 break; |
| 490 } | 492 } |
| 491 #if defined(OS_IOS) | 493 #if defined(OS_IOS) |
| 492 case kImageRepCocoaTouch: { | 494 case kImageRepCocoaTouch: { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 512 CHECK(scoped_rep); | 514 CHECK(scoped_rep); |
| 513 rep = AddRepresentation(std::move(scoped_rep)); | 515 rep = AddRepresentation(std::move(scoped_rep)); |
| 514 } | 516 } |
| 515 return rep->AsImageRepSkia()->image(); | 517 return rep->AsImageRepSkia()->image(); |
| 516 } | 518 } |
| 517 | 519 |
| 518 #if defined(OS_IOS) | 520 #if defined(OS_IOS) |
| 519 UIImage* Image::ToUIImage() const { | 521 UIImage* Image::ToUIImage() const { |
| 520 internal::ImageRep* rep = GetRepresentation(kImageRepCocoaTouch, false); | 522 internal::ImageRep* rep = GetRepresentation(kImageRepCocoaTouch, false); |
| 521 if (!rep) { | 523 if (!rep) { |
| 522 scoped_ptr<internal::ImageRep> scoped_rep; | 524 std::unique_ptr<internal::ImageRep> scoped_rep; |
| 523 switch (DefaultRepresentationType()) { | 525 switch (DefaultRepresentationType()) { |
| 524 case kImageRepPNG: { | 526 case kImageRepPNG: { |
| 525 internal::ImageRepPNG* png_rep = | 527 internal::ImageRepPNG* png_rep = |
| 526 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); | 528 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); |
| 527 scoped_rep.reset(new internal::ImageRepCocoaTouch( | 529 scoped_rep.reset(new internal::ImageRepCocoaTouch( |
| 528 internal::CreateUIImageFromPNG(png_rep->image_reps()))); | 530 internal::CreateUIImageFromPNG(png_rep->image_reps()))); |
| 529 break; | 531 break; |
| 530 } | 532 } |
| 531 case kImageRepSkia: { | 533 case kImageRepSkia: { |
| 532 internal::ImageRepSkia* skia_rep = | 534 internal::ImageRepSkia* skia_rep = |
| 533 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); | 535 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
| 534 UIImage* image = UIImageFromImageSkia(*skia_rep->image()); | 536 UIImage* image = UIImageFromImageSkia(*skia_rep->image()); |
| 535 base::mac::NSObjectRetain(image); | 537 base::mac::NSObjectRetain(image); |
| 536 scoped_rep.reset(new internal::ImageRepCocoaTouch(image)); | 538 scoped_rep.reset(new internal::ImageRepCocoaTouch(image)); |
| 537 break; | 539 break; |
| 538 } | 540 } |
| 539 default: | 541 default: |
| 540 NOTREACHED(); | 542 NOTREACHED(); |
| 541 } | 543 } |
| 542 CHECK(scoped_rep); | 544 CHECK(scoped_rep); |
| 543 rep = AddRepresentation(std::move(scoped_rep)); | 545 rep = AddRepresentation(std::move(scoped_rep)); |
| 544 } | 546 } |
| 545 return rep->AsImageRepCocoaTouch()->image(); | 547 return rep->AsImageRepCocoaTouch()->image(); |
| 546 } | 548 } |
| 547 #elif defined(OS_MACOSX) | 549 #elif defined(OS_MACOSX) |
| 548 NSImage* Image::ToNSImage() const { | 550 NSImage* Image::ToNSImage() const { |
| 549 internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false); | 551 internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false); |
| 550 if (!rep) { | 552 if (!rep) { |
| 551 scoped_ptr<internal::ImageRep> scoped_rep; | 553 std::unique_ptr<internal::ImageRep> scoped_rep; |
| 552 CGColorSpaceRef default_representation_color_space = | 554 CGColorSpaceRef default_representation_color_space = |
| 553 storage_->default_representation_color_space(); | 555 storage_->default_representation_color_space(); |
| 554 | 556 |
| 555 switch (DefaultRepresentationType()) { | 557 switch (DefaultRepresentationType()) { |
| 556 case kImageRepPNG: { | 558 case kImageRepPNG: { |
| 557 internal::ImageRepPNG* png_rep = | 559 internal::ImageRepPNG* png_rep = |
| 558 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); | 560 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); |
| 559 scoped_rep.reset(new internal::ImageRepCocoa(internal::NSImageFromPNG( | 561 scoped_rep.reset(new internal::ImageRepCocoa(internal::NSImageFromPNG( |
| 560 png_rep->image_reps(), default_representation_color_space))); | 562 png_rep->image_reps(), default_representation_color_space))); |
| 561 break; | 563 break; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); | 621 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
| 620 png_bytes = internal::Get1xPNGBytesFromImageSkia(skia_rep->image()); | 622 png_bytes = internal::Get1xPNGBytesFromImageSkia(skia_rep->image()); |
| 621 break; | 623 break; |
| 622 } | 624 } |
| 623 default: | 625 default: |
| 624 NOTREACHED(); | 626 NOTREACHED(); |
| 625 } | 627 } |
| 626 if (!png_bytes.get() || !png_bytes->size()) { | 628 if (!png_bytes.get() || !png_bytes->size()) { |
| 627 // Add an ImageRepPNG with no data such that the conversion is not | 629 // Add an ImageRepPNG with no data such that the conversion is not |
| 628 // attempted each time we want the PNG bytes. | 630 // attempted each time we want the PNG bytes. |
| 629 AddRepresentation(make_scoped_ptr(new internal::ImageRepPNG())); | 631 AddRepresentation(base::WrapUnique(new internal::ImageRepPNG())); |
| 630 return new base::RefCountedBytes(); | 632 return new base::RefCountedBytes(); |
| 631 } | 633 } |
| 632 | 634 |
| 633 // Do not insert representations for scale factors other than 1x even if | 635 // Do not insert representations for scale factors other than 1x even if |
| 634 // they are available because: | 636 // they are available because: |
| 635 // - Only the 1x PNG bytes can be accessed. | 637 // - Only the 1x PNG bytes can be accessed. |
| 636 // - ImageRepPNG is not used as an intermediate type in converting to a | 638 // - ImageRepPNG is not used as an intermediate type in converting to a |
| 637 // final type eg (converting from ImageRepSkia to ImageRepPNG to get an | 639 // final type eg (converting from ImageRepSkia to ImageRepPNG to get an |
| 638 // ImageRepCocoa). | 640 // ImageRepCocoa). |
| 639 std::vector<ImagePNGRep> image_png_reps; | 641 std::vector<ImagePNGRep> image_png_reps; |
| 640 image_png_reps.push_back(ImagePNGRep(png_bytes, 1.0f)); | 642 image_png_reps.push_back(ImagePNGRep(png_bytes, 1.0f)); |
| 641 AddRepresentation(make_scoped_ptr(new internal::ImageRepPNG(image_png_reps))); | 643 AddRepresentation( |
| 644 base::WrapUnique(new internal::ImageRepPNG(image_png_reps))); |
| 642 return png_bytes; | 645 return png_bytes; |
| 643 } | 646 } |
| 644 | 647 |
| 645 SkBitmap Image::AsBitmap() const { | 648 SkBitmap Image::AsBitmap() const { |
| 646 return IsEmpty() ? SkBitmap() : *ToSkBitmap(); | 649 return IsEmpty() ? SkBitmap() : *ToSkBitmap(); |
| 647 } | 650 } |
| 648 | 651 |
| 649 ImageSkia Image::AsImageSkia() const { | 652 ImageSkia Image::AsImageSkia() const { |
| 650 return IsEmpty() ? ImageSkia() : *ToImageSkia(); | 653 return IsEmpty() ? ImageSkia() : *ToImageSkia(); |
| 651 } | 654 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 RepresentationMap::const_iterator it = | 743 RepresentationMap::const_iterator it = |
| 741 storage_->representations().find(rep_type); | 744 storage_->representations().find(rep_type); |
| 742 if (it == storage_->representations().end()) { | 745 if (it == storage_->representations().end()) { |
| 743 CHECK(!must_exist); | 746 CHECK(!must_exist); |
| 744 return NULL; | 747 return NULL; |
| 745 } | 748 } |
| 746 return it->second.get(); | 749 return it->second.get(); |
| 747 } | 750 } |
| 748 | 751 |
| 749 internal::ImageRep* Image::AddRepresentation( | 752 internal::ImageRep* Image::AddRepresentation( |
| 750 scoped_ptr<internal::ImageRep> rep) const { | 753 std::unique_ptr<internal::ImageRep> rep) const { |
| 751 CHECK(storage_.get()); | 754 CHECK(storage_.get()); |
| 752 RepresentationType type = rep->type(); | 755 RepresentationType type = rep->type(); |
| 753 auto result = | 756 auto result = |
| 754 storage_->representations().insert(std::make_pair(type, std::move(rep))); | 757 storage_->representations().insert(std::make_pair(type, std::move(rep))); |
| 755 | 758 |
| 756 // insert should not fail (implies that there was already a representation of | 759 // insert should not fail (implies that there was already a representation of |
| 757 // that type in the map). | 760 // that type in the map). |
| 758 CHECK(result.second) << "type was already in map."; | 761 CHECK(result.second) << "type was already in map."; |
| 759 | 762 |
| 760 return result.first->second.get(); | 763 return result.first->second.get(); |
| 761 } | 764 } |
| 762 | 765 |
| 763 } // namespace gfx | 766 } // namespace gfx |
| OLD | NEW |