Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(396)

Side by Side Diff: ui/gfx/image/image.cc

Issue 1099473003: gfx::Image: AddRepresentation takes a scoped_ptr, not a raw ptr. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@base-scopedmap
Patch Set: Fix potential null dereference (use after release). Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/image/image.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/gfx/image/image.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698