Index: ui/gfx/image/image.cc |
diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc |
index c5d30a29210fbf4db294a8f4df3189e27a2c739d..47d0a85aded812efd44c5c790d88cbb614c28683 100644 |
--- a/ui/gfx/image/image.cc |
+++ b/ui/gfx/image/image.cc |
@@ -9,6 +9,8 @@ |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "third_party/skia/include/core/SkBitmap.h" |
+#include "ui/gfx/codec/png_codec.h" |
+#include "ui/gfx/image/image_png.h" |
#include "ui/gfx/image/image_skia.h" |
#include "ui/gfx/size.h" |
@@ -41,6 +43,14 @@ const ImageSkia ImageSkiaFromGdkPixbuf(GdkPixbuf* pixbuf) { |
} |
#endif |
+const ImageSkia ImageSkiaFromImagePNG(const ImagePNG& png) { |
+ SkBitmap bitmap; |
+ if (!gfx::PNGCodec::Decode(&png.Image().front(), png.Image().size(), &bitmap)) |
+ LOG(WARNING) << "Unable to decode PNG, returning empty bitmap"; |
+ return ImageSkia(bitmap); |
+} |
+ |
+class ImageRepPNG; |
class ImageRepSkia; |
class ImageRepGdk; |
class ImageRepCairo; |
@@ -59,6 +69,11 @@ class ImageRep { |
virtual ~ImageRep() {} |
// Cast helpers ("fake RTTI"). |
+ ImageRepPNG* AsImageRepPNG() { |
+ CHECK_EQ(type_, Image::kImageRepPNG); |
+ return reinterpret_cast<ImageRepPNG*>(this); |
+ } |
+ |
ImageRepSkia* AsImageRepSkia() { |
CHECK_EQ(type_, Image::kImageRepSkia); |
return reinterpret_cast<ImageRepSkia*>(this); |
@@ -89,6 +104,24 @@ class ImageRep { |
Image::RepresentationType type_; |
}; |
+class ImageRepPNG : public ImageRep { |
+ public: |
+ explicit ImageRepPNG(const ImagePNG& png) |
+ : ImageRep(Image::kImageRepPNG), |
+ image_(png) { |
+ } |
+ |
+ virtual ~ImageRepPNG() { |
+ } |
+ |
+ const ImagePNG& image() const { return image_; } |
+ |
+ private: |
+ ImagePNG image_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ImageRepPNG); |
+}; |
+ |
class ImageRepSkia : public ImageRep { |
public: |
// Takes ownership of |image|. |
@@ -219,6 +252,12 @@ Image::Image() { |
// |storage_| is NULL for empty Images. |
} |
+Image::Image(const ImagePNG& image) |
+ : storage_(new internal::ImageStorage(Image::kImageRepPNG)) { |
+ internal::ImageRepPNG* rep = new internal::ImageRepPNG(image); |
+ AddRepresentation(rep); |
+} |
+ |
Image::Image(const ImageSkia& image) |
: storage_(new internal::ImageStorage(Image::kImageRepSkia)) { |
internal::ImageRepSkia* rep = new internal::ImageRepSkia( |
@@ -267,6 +306,35 @@ Image& Image::operator=(const Image& other) { |
Image::~Image() { |
} |
+const ImagePNG* Image::ToImagePNG() const { |
+ internal::ImageRep* rep = GetRepresentation(kImageRepPNG, false); |
+ if (!rep) { |
+ switch (DefaultRepresentationType()) { |
+ // For both native types, ensure that there is an ImageRepSkia and fall |
+ // through to that case |
+#if defined(TOOLKIT_GTK) |
+ case kImageRepGdk: |
+ ToImageSkia(); |
+#elif defined(OS_MACOSX) |
+ case kImageRepCocoa: |
+ ToImageSkia(); |
+#endif |
+ case kImageRepSkia: { |
+ internal::ImageRepSkia* skia_rep = |
+ GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
+ rep = new internal::ImageRepPNG( |
+ ImagePNG::FromSkBitmap(skia_rep->image()->bitmap())); |
+ break; |
+ } |
+ default: |
+ NOTREACHED(); |
+ } |
+ CHECK(rep); |
+ AddRepresentation(rep); |
+ } |
+ return &rep->AsImageRepPNG()->image(); |
+} |
+ |
const SkBitmap* Image::ToSkBitmap() const { |
// Possibly create and cache an intermediate ImageRepSkia. |
return ToImageSkia()->bitmap(); |
@@ -275,17 +343,34 @@ const SkBitmap* Image::ToSkBitmap() const { |
const ImageSkia* Image::ToImageSkia() const { |
internal::ImageRep* rep = GetRepresentation(kImageRepSkia, false); |
if (!rep) { |
+ switch (DefaultRepresentationType()) { |
+ case kImageRepPNG: { |
+ internal::ImageRepPNG* png_rep = |
+ GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); |
+ rep = new internal::ImageRepSkia(new ImageSkia( |
+ internal::ImageSkiaFromImagePNG(png_rep->image()))); |
+ break; |
+ } |
#if defined(TOOLKIT_GTK) |
- internal::ImageRepGdk* native_rep = |
- GetRepresentation(kImageRepGdk, true)->AsImageRepGdk(); |
- rep = new internal::ImageRepSkia(new ImageSkia( |
- internal::ImageSkiaFromGdkPixbuf(native_rep->pixbuf()))); |
+ case kImageRepGdk: { |
+ internal::ImageRepGdk* native_rep = |
+ GetRepresentation(kImageRepGdk, true)->AsImageRepGdk(); |
+ rep = new internal::ImageRepSkia(new ImageSkia( |
+ internal::ImageSkiaFromGdkPixbuf(native_rep->pixbuf()))); |
+ break; |
+ } |
#elif defined(OS_MACOSX) |
- internal::ImageRepCocoa* native_rep = |
- GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa(); |
- rep = new internal::ImageRepSkia(new ImageSkia( |
- ImageSkiaFromNSImage(native_rep->image()))); |
+ case kImageRepCocoa: { |
+ internal::ImageRepCocoa* native_rep = |
+ GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa(); |
+ rep = new internal::ImageRepSkia(new ImageSkia( |
+ ImageSkiaFromNSImage(native_rep->image()))); |
+ break; |
+ } |
#endif |
+ default: |
+ NOTREACHED(); |
+ } |
CHECK(rep); |
AddRepresentation(rep); |
} |
@@ -296,10 +381,20 @@ const ImageSkia* Image::ToImageSkia() const { |
GdkPixbuf* Image::ToGdkPixbuf() const { |
internal::ImageRep* rep = GetRepresentation(kImageRepGdk, false); |
if (!rep) { |
- internal::ImageRepSkia* skia_rep = |
- GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
- rep = new internal::ImageRepGdk(gfx::GdkPixbufFromSkBitmap( |
- *skia_rep->image()->bitmap())); |
+ switch (DefaultRepresentationType()) { |
+ case kImageRepPNG: |
+ // Ensure that there is an ImageRepSkia and fall through to that case. |
+ ToImageSkia(); |
+ case kImageRepSkia: { |
+ internal::ImageRepSkia* skia_rep = |
+ GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
+ rep = new internal::ImageRepGdk(gfx::GdkPixbufFromSkBitmap( |
+ *skia_rep->image()->bitmap())); |
+ break; |
+ } |
+ default: |
+ NOTREACHED(); |
+ } |
CHECK(rep); |
AddRepresentation(rep); |
} |
@@ -323,11 +418,21 @@ CairoCachedSurface* const Image::ToCairo() const { |
NSImage* Image::ToNSImage() const { |
internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false); |
if (!rep) { |
- internal::ImageRepSkia* skia_rep = |
- GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
- NSImage* image = NSImageFromImageSkia(*skia_rep->image()); |
- base::mac::NSObjectRetain(image); |
- rep = new internal::ImageRepCocoa(image); |
+ switch (DefaultRepresentationType()) { |
+ case kImageRepPNG: |
+ // Ensure that there is a ImageRepSkia and fall through to that case. |
+ ToImageSkia(); |
+ case kImageRepSkia: { |
+ internal::ImageRepSkia* skia_rep = |
+ GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); |
+ NSImage* image = NSImageFromImageSkia(*skia_rep->image()); |
+ base::mac::NSObjectRetain(image); |
+ rep = new internal::ImageRepCocoa(image); |
+ break; |
+ } |
+ default: |
+ NOTREACHED(); |
+ } |
CHECK(rep); |
AddRepresentation(rep); |
} |
@@ -335,6 +440,10 @@ NSImage* Image::ToNSImage() const { |
} |
#endif |
+ImagePNG* Image::CopyImagePNG() const { |
+ return new ImagePNG(*ToImagePNG()); |
+} |
+ |
ImageSkia* Image::CopyImageSkia() const { |
return new ImageSkia(*ToImageSkia()); |
} |