| 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 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | |
| 12 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 13 #include "third_party/skia/include/core/SkBitmap.h" | 12 #include "third_party/skia/include/core/SkBitmap.h" |
| 14 #include "ui/gfx/geometry/size.h" | 13 #include "ui/gfx/geometry/size.h" |
| 15 #include "ui/gfx/image/image_png_rep.h" | 14 #include "ui/gfx/image/image_png_rep.h" |
| 16 #include "ui/gfx/image/image_skia.h" | 15 #include "ui/gfx/image/image_skia.h" |
| 17 #include "ui/gfx/image/image_skia_source.h" | 16 #include "ui/gfx/image/image_skia_source.h" |
| 18 | 17 |
| 19 #if !defined(OS_IOS) | 18 #if !defined(OS_IOS) |
| 20 #include "ui/gfx/codec/png_codec.h" | 19 #include "ui/gfx/codec/png_codec.h" |
| 21 #endif | 20 #endif |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 std::vector<ImagePNGRep> filtered; | 399 std::vector<ImagePNGRep> filtered; |
| 401 for (size_t i = 0; i < image_reps.size(); ++i) { | 400 for (size_t i = 0; i < image_reps.size(); ++i) { |
| 402 if (image_reps[i].raw_data.get() && image_reps[i].raw_data->size()) | 401 if (image_reps[i].raw_data.get() && image_reps[i].raw_data->size()) |
| 403 filtered.push_back(image_reps[i]); | 402 filtered.push_back(image_reps[i]); |
| 404 } | 403 } |
| 405 | 404 |
| 406 if (filtered.empty()) | 405 if (filtered.empty()) |
| 407 return; | 406 return; |
| 408 | 407 |
| 409 storage_ = new internal::ImageStorage(Image::kImageRepPNG); | 408 storage_ = new internal::ImageStorage(Image::kImageRepPNG); |
| 410 internal::ImageRepPNG* rep = new internal::ImageRepPNG(filtered); | 409 AddRepresentation(make_scoped_ptr(new internal::ImageRepPNG(filtered))); |
| 411 AddRepresentation(rep); | |
| 412 } | 410 } |
| 413 | 411 |
| 414 Image::Image(const ImageSkia& image) { | 412 Image::Image(const ImageSkia& image) { |
| 415 if (!image.isNull()) { | 413 if (!image.isNull()) { |
| 416 storage_ = new internal::ImageStorage(Image::kImageRepSkia); | 414 storage_ = new internal::ImageStorage(Image::kImageRepSkia); |
| 417 internal::ImageRepSkia* rep = new internal::ImageRepSkia( | 415 AddRepresentation( |
| 418 new ImageSkia(image)); | 416 make_scoped_ptr(new internal::ImageRepSkia(new ImageSkia(image)))); |
| 419 AddRepresentation(rep); | |
| 420 } | 417 } |
| 421 } | 418 } |
| 422 | 419 |
| 423 #if defined(OS_IOS) | 420 #if defined(OS_IOS) |
| 424 Image::Image(UIImage* image) | 421 Image::Image(UIImage* image) |
| 425 : storage_(new internal::ImageStorage(Image::kImageRepCocoaTouch)) { | 422 : storage_(new internal::ImageStorage(Image::kImageRepCocoaTouch)) { |
| 426 if (image) { | 423 if (image) |
| 427 internal::ImageRepCocoaTouch* rep = new internal::ImageRepCocoaTouch(image); | 424 AddRepresentation(make_scoped_ptr(new internal::ImageRepCocoaTouch(image))); |
| 428 AddRepresentation(rep); | |
| 429 } | |
| 430 } | 425 } |
| 431 #elif defined(OS_MACOSX) | 426 #elif defined(OS_MACOSX) |
| 432 Image::Image(NSImage* image) { | 427 Image::Image(NSImage* image) { |
| 433 if (image) { | 428 if (image) { |
| 434 storage_ = new internal::ImageStorage(Image::kImageRepCocoa); | 429 storage_ = new internal::ImageStorage(Image::kImageRepCocoa); |
| 435 internal::ImageRepCocoa* rep = new internal::ImageRepCocoa(image); | 430 AddRepresentation(make_scoped_ptr(new internal::ImageRepCocoa(image))); |
| 436 AddRepresentation(rep); | |
| 437 } | 431 } |
| 438 } | 432 } |
| 439 #endif | 433 #endif |
| 440 | 434 |
| 441 Image::Image(const Image& other) : storage_(other.storage_) { | 435 Image::Image(const Image& other) : storage_(other.storage_) { |
| 442 } | 436 } |
| 443 | 437 |
| 444 Image& Image::operator=(const Image& other) { | 438 Image& Image::operator=(const Image& other) { |
| 445 storage_ = other.storage_; | 439 storage_ = other.storage_; |
| 446 return *this; | 440 return *this; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 477 } | 471 } |
| 478 | 472 |
| 479 const SkBitmap* Image::ToSkBitmap() const { | 473 const SkBitmap* Image::ToSkBitmap() const { |
| 480 // Possibly create and cache an intermediate ImageRepSkia. | 474 // Possibly create and cache an intermediate ImageRepSkia. |
| 481 return ToImageSkia()->bitmap(); | 475 return ToImageSkia()->bitmap(); |
| 482 } | 476 } |
| 483 | 477 |
| 484 const ImageSkia* Image::ToImageSkia() const { | 478 const ImageSkia* Image::ToImageSkia() const { |
| 485 internal::ImageRep* rep = GetRepresentation(kImageRepSkia, false); | 479 internal::ImageRep* rep = GetRepresentation(kImageRepSkia, false); |
| 486 if (!rep) { | 480 if (!rep) { |
| 481 scoped_ptr<internal::ImageRep> scoped_rep; |
| 487 switch (DefaultRepresentationType()) { | 482 switch (DefaultRepresentationType()) { |
| 488 case kImageRepPNG: { | 483 case kImageRepPNG: { |
| 489 internal::ImageRepPNG* png_rep = | 484 internal::ImageRepPNG* png_rep = |
| 490 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); | 485 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); |
| 491 rep = new internal::ImageRepSkia( | 486 scoped_rep.reset(new internal::ImageRepSkia( |
| 492 internal::ImageSkiaFromPNG(png_rep->image_reps())); | 487 internal::ImageSkiaFromPNG(png_rep->image_reps()))); |
| 493 break; | 488 break; |
| 494 } | 489 } |
| 495 #if defined(OS_IOS) | 490 #if defined(OS_IOS) |
| 496 case kImageRepCocoaTouch: { | 491 case kImageRepCocoaTouch: { |
| 497 internal::ImageRepCocoaTouch* native_rep = | 492 internal::ImageRepCocoaTouch* native_rep = |
| 498 GetRepresentation(kImageRepCocoaTouch, true) | 493 GetRepresentation(kImageRepCocoaTouch, true) |
| 499 ->AsImageRepCocoaTouch(); | 494 ->AsImageRepCocoaTouch(); |
| 500 rep = new internal::ImageRepSkia(new ImageSkia( | 495 scoped_rep.reset(new internal::ImageRepSkia( |
| 501 ImageSkiaFromUIImage(native_rep->image()))); | 496 new ImageSkia(ImageSkiaFromUIImage(native_rep->image())))); |
| 502 break; | 497 break; |
| 503 } | 498 } |
| 504 #elif defined(OS_MACOSX) | 499 #elif defined(OS_MACOSX) |
| 505 case kImageRepCocoa: { | 500 case kImageRepCocoa: { |
| 506 internal::ImageRepCocoa* native_rep = | 501 internal::ImageRepCocoa* native_rep = |
| 507 GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa(); | 502 GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa(); |
| 508 rep = new internal::ImageRepSkia(new ImageSkia( | 503 scoped_rep.reset(new internal::ImageRepSkia( |
| 509 ImageSkiaFromNSImage(native_rep->image()))); | 504 new ImageSkia(ImageSkiaFromNSImage(native_rep->image())))); |
| 510 break; | 505 break; |
| 511 } | 506 } |
| 512 #endif | 507 #endif |
| 513 default: | 508 default: |
| 514 NOTREACHED(); | 509 NOTREACHED(); |
| 515 } | 510 } |
| 516 CHECK(rep); | 511 CHECK(scoped_rep); |
| 517 AddRepresentation(rep); | 512 rep = scoped_rep.get(); |
| 513 AddRepresentation(scoped_rep.Pass()); |
| 518 } | 514 } |
| 519 return rep->AsImageRepSkia()->image(); | 515 return rep->AsImageRepSkia()->image(); |
| 520 } | 516 } |
| 521 | 517 |
| 522 #if defined(OS_IOS) | 518 #if defined(OS_IOS) |
| 523 UIImage* Image::ToUIImage() const { | 519 UIImage* Image::ToUIImage() const { |
| 524 internal::ImageRep* rep = GetRepresentation(kImageRepCocoaTouch, false); | 520 internal::ImageRep* rep = GetRepresentation(kImageRepCocoaTouch, false); |
| 525 if (!rep) { | 521 if (!rep) { |
| 522 scoped_ptr<internal::ImageRep> scoped_rep; |
| 526 switch (DefaultRepresentationType()) { | 523 switch (DefaultRepresentationType()) { |
| 527 case kImageRepPNG: { | 524 case kImageRepPNG: { |
| 528 internal::ImageRepPNG* png_rep = | 525 internal::ImageRepPNG* png_rep = |
| 529 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); | 526 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); |
| 530 rep = new internal::ImageRepCocoaTouch(internal::CreateUIImageFromPNG( | 527 scoped_rep.reset(new internal::ImageRepCocoaTouch( |
| 531 png_rep->image_reps())); | 528 internal::CreateUIImageFromPNG(png_rep->image_reps()))); |
| 532 break; | 529 break; |
| 533 } | 530 } |
| 534 case kImageRepSkia: { | 531 case kImageRepSkia: { |
| 535 internal::ImageRepSkia* skia_rep = | 532 internal::ImageRepSkia* skia_rep = |
| 536 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); | 533 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
| 537 UIImage* image = UIImageFromImageSkia(*skia_rep->image()); | 534 UIImage* image = UIImageFromImageSkia(*skia_rep->image()); |
| 538 base::mac::NSObjectRetain(image); | 535 base::mac::NSObjectRetain(image); |
| 539 rep = new internal::ImageRepCocoaTouch(image); | 536 scoped_rep.reset(new internal::ImageRepCocoaTouch(image)); |
| 540 break; | 537 break; |
| 541 } | 538 } |
| 542 default: | 539 default: |
| 543 NOTREACHED(); | 540 NOTREACHED(); |
| 544 } | 541 } |
| 545 CHECK(rep); | 542 CHECK(scoped_rep); |
| 546 AddRepresentation(rep); | 543 rep = scoped_rep.get(); |
| 544 AddRepresentation(scoped_rep.Pass()); |
| 547 } | 545 } |
| 548 return rep->AsImageRepCocoaTouch()->image(); | 546 return rep->AsImageRepCocoaTouch()->image(); |
| 549 } | 547 } |
| 550 #elif defined(OS_MACOSX) | 548 #elif defined(OS_MACOSX) |
| 551 NSImage* Image::ToNSImage() const { | 549 NSImage* Image::ToNSImage() const { |
| 552 internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false); | 550 internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false); |
| 553 if (!rep) { | 551 if (!rep) { |
| 552 scoped_ptr<internal::ImageRep> scoped_rep; |
| 554 CGColorSpaceRef default_representation_color_space = | 553 CGColorSpaceRef default_representation_color_space = |
| 555 storage_->default_representation_color_space(); | 554 storage_->default_representation_color_space(); |
| 556 | 555 |
| 557 switch (DefaultRepresentationType()) { | 556 switch (DefaultRepresentationType()) { |
| 558 case kImageRepPNG: { | 557 case kImageRepPNG: { |
| 559 internal::ImageRepPNG* png_rep = | 558 internal::ImageRepPNG* png_rep = |
| 560 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); | 559 GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); |
| 561 rep = new internal::ImageRepCocoa(internal::NSImageFromPNG( | 560 scoped_rep.reset(new internal::ImageRepCocoa(internal::NSImageFromPNG( |
| 562 png_rep->image_reps(), default_representation_color_space)); | 561 png_rep->image_reps(), default_representation_color_space))); |
| 563 break; | 562 break; |
| 564 } | 563 } |
| 565 case kImageRepSkia: { | 564 case kImageRepSkia: { |
| 566 internal::ImageRepSkia* skia_rep = | 565 internal::ImageRepSkia* skia_rep = |
| 567 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); | 566 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
| 568 NSImage* image = NSImageFromImageSkiaWithColorSpace(*skia_rep->image(), | 567 NSImage* image = NSImageFromImageSkiaWithColorSpace(*skia_rep->image(), |
| 569 default_representation_color_space); | 568 default_representation_color_space); |
| 570 base::mac::NSObjectRetain(image); | 569 base::mac::NSObjectRetain(image); |
| 571 rep = new internal::ImageRepCocoa(image); | 570 scoped_rep.reset(new internal::ImageRepCocoa(image)); |
| 572 break; | 571 break; |
| 573 } | 572 } |
| 574 default: | 573 default: |
| 575 NOTREACHED(); | 574 NOTREACHED(); |
| 576 } | 575 } |
| 577 CHECK(rep); | 576 CHECK(scoped_rep); |
| 578 AddRepresentation(rep); | 577 rep = scoped_rep.get(); |
| 578 AddRepresentation(scoped_rep.Pass()); |
| 579 } | 579 } |
| 580 return rep->AsImageRepCocoa()->image(); | 580 return rep->AsImageRepCocoa()->image(); |
| 581 } | 581 } |
| 582 #endif | 582 #endif |
| 583 | 583 |
| 584 scoped_refptr<base::RefCountedMemory> Image::As1xPNGBytes() const { | 584 scoped_refptr<base::RefCountedMemory> Image::As1xPNGBytes() const { |
| 585 if (IsEmpty()) | 585 if (IsEmpty()) |
| 586 return new base::RefCountedBytes(); | 586 return new base::RefCountedBytes(); |
| 587 | 587 |
| 588 internal::ImageRep* rep = GetRepresentation(kImageRepPNG, false); | 588 internal::ImageRep* rep = GetRepresentation(kImageRepPNG, false); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); | 621 GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
| 622 png_bytes = internal::Get1xPNGBytesFromImageSkia(skia_rep->image()); | 622 png_bytes = internal::Get1xPNGBytesFromImageSkia(skia_rep->image()); |
| 623 break; | 623 break; |
| 624 } | 624 } |
| 625 default: | 625 default: |
| 626 NOTREACHED(); | 626 NOTREACHED(); |
| 627 } | 627 } |
| 628 if (!png_bytes.get() || !png_bytes->size()) { | 628 if (!png_bytes.get() || !png_bytes->size()) { |
| 629 // 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 |
| 630 // attempted each time we want the PNG bytes. | 630 // attempted each time we want the PNG bytes. |
| 631 AddRepresentation(new internal::ImageRepPNG()); | 631 AddRepresentation(make_scoped_ptr(new internal::ImageRepPNG())); |
| 632 return new base::RefCountedBytes(); | 632 return new base::RefCountedBytes(); |
| 633 } | 633 } |
| 634 | 634 |
| 635 // 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 |
| 636 // they are available because: | 636 // they are available because: |
| 637 // - Only the 1x PNG bytes can be accessed. | 637 // - Only the 1x PNG bytes can be accessed. |
| 638 // - 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 |
| 639 // final type eg (converting from ImageRepSkia to ImageRepPNG to get an | 639 // final type eg (converting from ImageRepSkia to ImageRepPNG to get an |
| 640 // ImageRepCocoa). | 640 // ImageRepCocoa). |
| 641 std::vector<ImagePNGRep> image_png_reps; | 641 std::vector<ImagePNGRep> image_png_reps; |
| 642 image_png_reps.push_back(ImagePNGRep(png_bytes, 1.0f)); | 642 image_png_reps.push_back(ImagePNGRep(png_bytes, 1.0f)); |
| 643 rep = new internal::ImageRepPNG(image_png_reps); | 643 AddRepresentation(make_scoped_ptr(new internal::ImageRepPNG(image_png_reps))); |
| 644 AddRepresentation(rep); | |
| 645 return png_bytes; | 644 return png_bytes; |
| 646 } | 645 } |
| 647 | 646 |
| 648 SkBitmap Image::AsBitmap() const { | 647 SkBitmap Image::AsBitmap() const { |
| 649 return IsEmpty() ? SkBitmap() : *ToSkBitmap(); | 648 return IsEmpty() ? SkBitmap() : *ToSkBitmap(); |
| 650 } | 649 } |
| 651 | 650 |
| 652 ImageSkia Image::AsImageSkia() const { | 651 ImageSkia Image::AsImageSkia() const { |
| 653 return IsEmpty() ? ImageSkia() : *ToImageSkia(); | 652 return IsEmpty() ? ImageSkia() : *ToImageSkia(); |
| 654 } | 653 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 RepresentationType rep_type, bool must_exist) const { | 740 RepresentationType rep_type, bool must_exist) const { |
| 742 CHECK(storage_.get()); | 741 CHECK(storage_.get()); |
| 743 RepresentationMap::iterator it = storage_->representations().find(rep_type); | 742 RepresentationMap::iterator it = storage_->representations().find(rep_type); |
| 744 if (it == storage_->representations().end()) { | 743 if (it == storage_->representations().end()) { |
| 745 CHECK(!must_exist); | 744 CHECK(!must_exist); |
| 746 return NULL; | 745 return NULL; |
| 747 } | 746 } |
| 748 return it->second; | 747 return it->second; |
| 749 } | 748 } |
| 750 | 749 |
| 751 void Image::AddRepresentation(internal::ImageRep* rep) const { | 750 void Image::AddRepresentation(scoped_ptr<internal::ImageRep> rep) const { |
| 752 CHECK(storage_.get()); | 751 CHECK(storage_.get()); |
| 753 storage_->representations().insert(std::make_pair(rep->type(), rep)); | 752 RepresentationType type = rep->type(); |
| 753 storage_->representations().insert(std::make_pair(type, rep.release())); |
| 754 } | 754 } |
| 755 | 755 |
| 756 } // namespace gfx | 756 } // namespace gfx |
| OLD | NEW |