Chromium Code Reviews| Index: ui/gfx/image/image.cc |
| diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc |
| index 5c81a5519ed6be6637bfbb8da200dfebd4ba061c..c063d85110d853ce924cbb31e4a0ef20b267b55f 100644 |
| --- a/ui/gfx/image/image.cc |
| +++ b/ui/gfx/image/image.cc |
| @@ -5,6 +5,7 @@ |
| #include "ui/gfx/image/image.h" |
| #include <algorithm> |
| +#include <set> |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| @@ -12,6 +13,7 @@ |
| #include "third_party/skia/include/core/SkBitmap.h" |
| #include "ui/gfx/image/image_png_rep.h" |
| #include "ui/gfx/image/image_skia.h" |
| +#include "ui/gfx/image/image_skia_source.h" |
| #include "ui/gfx/size.h" |
| #if !defined(OS_IOS) |
| @@ -35,20 +37,20 @@ scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage( |
| UIImage* uiimage); |
| // Caller takes ownership of the returned UIImage. |
| UIImage* CreateUIImageFromPNG( |
| - const std::vector<gfx::ImagePNGRep>& image_png_reps); |
| + const std::vector<ImagePNGRep>& image_png_reps); |
| gfx::Size UIImageSize(UIImage* image); |
| #elif defined(OS_MACOSX) |
| scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromNSImage( |
| NSImage* nsimage); |
| // Caller takes ownership of the returned NSImage. |
| -NSImage* NSImageFromPNG(const std::vector<gfx::ImagePNGRep>& image_png_reps, |
| +NSImage* NSImageFromPNG(const std::vector<ImagePNGRep>& image_png_reps, |
| CGColorSpaceRef color_space); |
| gfx::Size NSImageSize(NSImage* image); |
| #endif // defined(OS_MACOSX) |
| #if defined(OS_IOS) |
| ImageSkia* ImageSkiaFromPNG( |
| - const std::vector<gfx::ImagePNGRep>& image_png_reps); |
| + const std::vector<ImagePNGRep>& image_png_reps); |
| scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia( |
| const ImageSkia* skia); |
| #else |
| @@ -59,31 +61,89 @@ ImageSkia* GetErrorImageSkia() { |
| bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); |
| bitmap.allocPixels(); |
| bitmap.eraseARGB(0xff, 0xff, 0, 0); |
| - return new gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, 1.0f)); |
| + return new ImageSkia(ImageSkiaRep(bitmap, 1.0f)); |
| } |
| +class PNGImageSource : public ImageSkiaSource { |
| + public: |
| + PNGImageSource() {} |
| + virtual ~PNGImageSource() {} |
| + |
| + virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE { |
| + if (image_skia_reps_.empty()) |
| + return ImageSkiaRep(); |
| + |
| + const ImageSkiaRep* rep = NULL; |
|
pkotwicz
2014/06/19 14:16:13
Can you please cleanup the comments. Based on the
oshima
2014/06/19 15:50:40
will do.
oshima
2014/06/19 17:15:05
Done. (your description wasn't exactly correct. pl
|
| + for (ImageSkiaRepSet::const_iterator iter = image_skia_reps_.begin(); |
| + iter != image_skia_reps_.end(); ++iter) { |
| + if ((*iter).scale() == scale) |
| + return (*iter); |
| + // gfx::ImageSkia decides which the resource scale factor to use, |
| + // so just pick the larger scale. |
| + if (!rep || rep->scale() < (*iter).scale()) |
| + rep = &(*iter); |
| + // but if it's larger than the reuqsted scale, that's large enough. |
| + if (rep->scale() >= scale) |
| + break; |
| + } |
| + return rep ? *rep : ImageSkiaRep(); |
| + } |
| + |
| + const gfx::Size size() const { |
| + return size_; |
| + } |
| + |
| + bool AddPngData(const ImagePNGRep& png_rep) { |
| + const gfx::ImageSkiaRep rep = ToImageSkiaRep(png_rep); |
| + if (rep.is_null()) |
| + return false; |
| + if (size_.IsEmpty()) |
| + size_ = gfx::Size(rep.GetWidth(), rep.GetHeight()); |
| + image_skia_reps_.insert(rep); |
| + return true; |
| + } |
| + |
| + static ImageSkiaRep ToImageSkiaRep(const ImagePNGRep& png_rep) { |
| + scoped_refptr<base::RefCountedMemory> raw_data = png_rep.raw_data; |
| + CHECK(raw_data.get()); |
| + SkBitmap bitmap; |
| + if (!PNGCodec::Decode(raw_data->front(), raw_data->size(), |
| + &bitmap)) { |
| + LOG(ERROR) << "Unable to decode PNG for " << png_rep.scale << "."; |
| + return ImageSkiaRep(); |
| + } |
| + return ImageSkiaRep(bitmap, png_rep.scale); |
| + } |
| + |
| + private: |
| + struct Compare { |
| + bool operator()(const ImageSkiaRep& rep1, const ImageSkiaRep& rep2) { |
| + return rep1.scale() < rep2.scale(); |
| + } |
| + }; |
| + |
| + typedef std::set<ImageSkiaRep, Compare> ImageSkiaRepSet; |
| + ImageSkiaRepSet image_skia_reps_; |
| + gfx::Size size_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PNGImageSource); |
| +}; |
| + |
| ImageSkia* ImageSkiaFromPNG( |
| - const std::vector<gfx::ImagePNGRep>& image_png_reps) { |
| + const std::vector<ImagePNGRep>& image_png_reps) { |
| if (image_png_reps.empty()) |
| return GetErrorImageSkia(); |
| + scoped_ptr<PNGImageSource> image_source(new PNGImageSource); |
| - scoped_ptr<gfx::ImageSkia> image_skia(new ImageSkia()); |
| for (size_t i = 0; i < image_png_reps.size(); ++i) { |
| - scoped_refptr<base::RefCountedMemory> raw_data = |
| - image_png_reps[i].raw_data; |
| - CHECK(raw_data.get()); |
| - SkBitmap bitmap; |
| - if (!gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), |
| - &bitmap)) { |
| - LOG(ERROR) << "Unable to decode PNG for " |
| - << image_png_reps[i].scale |
| - << "."; |
| + if (!image_source->AddPngData(image_png_reps[i])) |
| return GetErrorImageSkia(); |
| - } |
| - image_skia->AddRepresentation(gfx::ImageSkiaRep( |
| - bitmap, image_png_reps[i].scale)); |
| } |
| - return image_skia.release(); |
| + const gfx::Size& size = image_source->size(); |
| + DCHECK(!size.IsEmpty()); |
| + if (size.IsEmpty()) |
| + return GetErrorImageSkia(); |
| + return new ImageSkia(image_source.release(), size); |
| } |
| scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia( |
| @@ -92,7 +152,7 @@ scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia( |
| scoped_refptr<base::RefCountedBytes> png_bytes(new base::RefCountedBytes()); |
| if (image_skia_rep.scale() != 1.0f || |
| - !gfx::PNGCodec::EncodeBGRASkBitmap(image_skia_rep.sk_bitmap(), false, |
| + !PNGCodec::EncodeBGRASkBitmap(image_skia_rep.sk_bitmap(), false, |
| &png_bytes->data())) { |
| return NULL; |
| } |
| @@ -302,7 +362,7 @@ class ImageRepCocoa : public ImageRep { |
| // ImageReps. This way, the Image can be cheaply copied. |
| class ImageStorage : public base::RefCounted<ImageStorage> { |
| public: |
| - ImageStorage(gfx::Image::RepresentationType default_type) |
| + ImageStorage(Image::RepresentationType default_type) |
| : default_representation_type_(default_type), |
| #if defined(OS_MACOSX) && !defined(OS_IOS) |
| default_representation_color_space_( |
| @@ -311,10 +371,10 @@ class ImageStorage : public base::RefCounted<ImageStorage> { |
| representations_deleter_(&representations_) { |
| } |
| - gfx::Image::RepresentationType default_representation_type() { |
| + Image::RepresentationType default_representation_type() { |
| return default_representation_type_; |
| } |
| - gfx::Image::RepresentationMap& representations() { return representations_; } |
| + Image::RepresentationMap& representations() { return representations_; } |
| #if defined(OS_MACOSX) && !defined(OS_IOS) |
| void set_default_representation_color_space(CGColorSpaceRef color_space) { |
| @@ -332,7 +392,7 @@ class ImageStorage : public base::RefCounted<ImageStorage> { |
| // The type of image that was passed to the constructor. This key will always |
| // exist in the |representations_| map. |
| - gfx::Image::RepresentationType default_representation_type_; |
| + Image::RepresentationType default_representation_type_; |
| #if defined(OS_MACOSX) && !defined(OS_IOS) |
| // The default representation's colorspace. This is used for converting to |
| @@ -344,7 +404,7 @@ class ImageStorage : public base::RefCounted<ImageStorage> { |
| // All the representations of an Image. Size will always be at least one, with |
| // more for any converted representations. |
| - gfx::Image::RepresentationMap representations_; |
| + Image::RepresentationMap representations_; |
| STLValueDeleter<Image::RepresentationMap> representations_deleter_; |
| @@ -413,14 +473,14 @@ Image::~Image() { |
| // static |
| Image Image::CreateFrom1xBitmap(const SkBitmap& bitmap) { |
| - return gfx::Image(ImageSkia::CreateFrom1xBitmap(bitmap)); |
| + return Image(ImageSkia::CreateFrom1xBitmap(bitmap)); |
| } |
| // static |
| Image Image::CreateFrom1xPNGBytes(const unsigned char* input, |
| size_t input_size) { |
| if (input_size == 0u) |
| - return gfx::Image(); |
| + return Image(); |
| scoped_refptr<base::RefCountedBytes> raw_data(new base::RefCountedBytes()); |
| raw_data->data().assign(input, input + input_size); |
| @@ -431,11 +491,11 @@ Image Image::CreateFrom1xPNGBytes(const unsigned char* input, |
| Image Image::CreateFrom1xPNGBytes( |
| const scoped_refptr<base::RefCountedMemory>& input) { |
| if (!input.get() || input->size() == 0u) |
| - return gfx::Image(); |
| + return Image(); |
| - std::vector<gfx::ImagePNGRep> image_reps; |
| + std::vector<ImagePNGRep> image_reps; |
| image_reps.push_back(ImagePNGRep(input, 1.0f)); |
| - return gfx::Image(image_reps); |
| + return Image(image_reps); |
| } |
| const SkBitmap* Image::ToSkBitmap() const { |
| @@ -550,7 +610,7 @@ scoped_refptr<base::RefCountedMemory> Image::As1xPNGBytes() const { |
| internal::ImageRep* rep = GetRepresentation(kImageRepPNG, false); |
| if (rep) { |
| - const std::vector<gfx::ImagePNGRep>& image_png_reps = |
| + const std::vector<ImagePNGRep>& image_png_reps = |
| rep->AsImageRepPNG()->image_reps(); |
| for (size_t i = 0; i < image_png_reps.size(); ++i) { |
| if (image_png_reps[i].scale == 1.0f) |
| @@ -601,7 +661,7 @@ scoped_refptr<base::RefCountedMemory> Image::As1xPNGBytes() const { |
| // final type eg (converting from ImageRepSkia to ImageRepPNG to get an |
| // ImageRepCocoa). |
| std::vector<ImagePNGRep> image_png_reps; |
| - image_png_reps.push_back(gfx::ImagePNGRep(png_bytes, 1.0f)); |
| + image_png_reps.push_back(ImagePNGRep(png_bytes, 1.0f)); |
| rep = new internal::ImageRepPNG(image_png_reps); |
| AddRepresentation(rep); |
| return png_bytes; |
| @@ -683,7 +743,7 @@ gfx::Size Image::Size() const { |
| return GetRepresentation(DefaultRepresentationType(), true)->Size(); |
| } |
| -void Image::SwapRepresentations(gfx::Image* other) { |
| +void Image::SwapRepresentations(Image* other) { |
| storage_.swap(other->storage_); |
| } |