15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 86d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_png_rep.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "ui/gfx/image/image_skia_source.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_IOS) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/foundation_util.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_util_ios.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_util.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_util_mac.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage( 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UIImage* uiimage); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Caller takes ownership of the returned UIImage. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UIImage* CreateUIImageFromPNG( 406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const std::vector<ImagePNGRep>& image_png_reps); 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Size UIImageSize(UIImage* image); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromNSImage( 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NSImage* nsimage); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Caller takes ownership of the returned NSImage. 466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)NSImage* NSImageFromPNG(const std::vector<ImagePNGRep>& image_png_reps, 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CGColorSpaceRef color_space); 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Size NSImageSize(NSImage* image); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_MACOSX) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ImageSkia* ImageSkiaFromPNG( 536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const std::vector<ImagePNGRep>& image_png_reps); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia( 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ImageSkia* skia); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns a 16x16 red image to visually show error in decoding PNG. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Caller takes ownership of returned ImageSkia. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ImageSkia* GetErrorImageSkia() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bitmap.allocN32Pixels(16, 16); 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bitmap.eraseARGB(0xff, 0xff, 0, 0); 636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return new ImageSkia(ImageSkiaRep(bitmap, 1.0f)); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class PNGImageSource : public ImageSkiaSource { 676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public: 686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) PNGImageSource() {} 696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) virtual ~PNGImageSource() {} 706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE { 726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (image_skia_reps_.empty()) 736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return ImageSkiaRep(); 746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const ImageSkiaRep* rep = NULL; 766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // gfx::ImageSkia passes one of the resource scale factors. The source 776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // should return: 786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // 1) The ImageSkiaRep with the highest scale if all available 796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // scales are smaller than |scale|. 806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // 2) The ImageSkiaRep with the smallest one that is larger than |scale|. 816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) for (ImageSkiaRepSet::const_iterator iter = image_skia_reps_.begin(); 826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) iter != image_skia_reps_.end(); ++iter) { 836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if ((*iter).scale() == scale) 846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return (*iter); 856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (!rep || rep->scale() < (*iter).scale()) 866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) rep = &(*iter); 876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (rep->scale() >= scale) 886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) break; 896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return rep ? *rep : ImageSkiaRep(); 916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const gfx::Size size() const { 946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return size_; 956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool AddPNGData(const ImagePNGRep& png_rep) { 986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const gfx::ImageSkiaRep rep = ToImageSkiaRep(png_rep); 996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (rep.is_null()) 1006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return false; 1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (size_.IsEmpty()) 1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) size_ = gfx::Size(rep.GetWidth(), rep.GetHeight()); 1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) image_skia_reps_.insert(rep); 1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return true; 1056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) static ImageSkiaRep ToImageSkiaRep(const ImagePNGRep& png_rep) { 1086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_refptr<base::RefCountedMemory> raw_data = png_rep.raw_data; 1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CHECK(raw_data.get()); 1106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) SkBitmap bitmap; 1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (!PNGCodec::Decode(raw_data->front(), raw_data->size(), 1126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) &bitmap)) { 1136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) LOG(ERROR) << "Unable to decode PNG for " << png_rep.scale << "."; 1146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return ImageSkiaRep(); 1156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return ImageSkiaRep(bitmap, png_rep.scale); 1176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private: 1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) struct Compare { 1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool operator()(const ImageSkiaRep& rep1, const ImageSkiaRep& rep2) { 1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return rep1.scale() < rep2.scale(); 1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) }; 1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) typedef std::set<ImageSkiaRep, Compare> ImageSkiaRepSet; 1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ImageSkiaRepSet image_skia_reps_; 1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) gfx::Size size_; 1296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PNGImageSource); 1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}; 1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ImageSkia* ImageSkiaFromPNG( 1346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const std::vector<ImagePNGRep>& image_png_reps) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (image_png_reps.empty()) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetErrorImageSkia(); 1376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<PNGImageSource> image_source(new PNGImageSource); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < image_png_reps.size(); ++i) { 1406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (!image_source->AddPNGData(image_png_reps[i])) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetErrorImageSkia(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const gfx::Size& size = image_source->size(); 1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(!size.IsEmpty()); 1456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (size.IsEmpty()) 1466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return GetErrorImageSkia(); 1476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return new ImageSkia(image_source.release(), size); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ImageSkia* image_skia) { 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ImageSkiaRep image_skia_rep = image_skia->GetRepresentation(1.0f); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedBytes> png_bytes(new base::RefCountedBytes()); 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (image_skia_rep.scale() != 1.0f || 1566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) !PNGCodec::EncodeBGRASkBitmap(image_skia_rep.sk_bitmap(), false, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &png_bytes->data())) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return png_bytes; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepPNG; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepSkia; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoa; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoaTouch; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An ImageRep is the object that holds the backing memory for an Image. Each 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RepresentationType has an ImageRep subclass that is responsible for freeing 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the memory that the ImageRep holds. When an ImageRep is created, it expects 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to take ownership of the image, without having to retain it or increase its 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference count. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRep { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ImageRep(Image::RepresentationType rep) : type_(rep) {} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the associated pixels of an ImageRep. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ImageRep() {} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cast helpers ("fake RTTI"). 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageRepPNG* AsImageRepPNG() { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(type_, Image::kImageRepPNG); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<ImageRepPNG*>(this); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageRepSkia* AsImageRepSkia() { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(type_, Image::kImageRepSkia); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<ImageRepSkia*>(this); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageRepCocoaTouch* AsImageRepCocoaTouch() { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(type_, Image::kImageRepCocoaTouch); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<ImageRepCocoaTouch*>(this); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageRepCocoa* AsImageRepCocoa() { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(type_, Image::kImageRepCocoa); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<ImageRepCocoa*>(this); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Image::RepresentationType type() const { return type_; } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Width() const = 0; 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Height() const = 0; 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual gfx::Size Size() const = 0; 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Image::RepresentationType type_; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepPNG : public ImageRep { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageRepPNG() : ImageRep(Image::kImageRepPNG) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ImageRepPNG(const std::vector<ImagePNGRep>& image_png_reps) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : ImageRep(Image::kImageRepPNG), 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_png_reps_(image_png_reps) { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ImageRepPNG() { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Width() const OVERRIDE { 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Size().width(); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Height() const OVERRIDE { 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Size().height(); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual gfx::Size Size() const OVERRIDE { 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Read the PNG data to get the image size, caching it. 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!size_cache_) { 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<ImagePNGRep>::const_iterator it = image_reps().begin(); 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it != image_reps().end(); ++it) { 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (it->scale == 1.0f) { 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_cache_.reset(new gfx::Size(it->Size())); 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *size_cache_; 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_cache_.reset(new gfx::Size); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *size_cache_; 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<ImagePNGRep>& image_reps() const { return image_png_reps_; } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ImagePNGRep> image_png_reps_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Cached to avoid having to parse the raw data multiple times. 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mutable scoped_ptr<gfx::Size> size_cache_; 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageRepPNG); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepSkia : public ImageRep { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Takes ownership of |image|. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ImageRepSkia(ImageSkia* image) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ImageRep(Image::kImageRepSkia), 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_(image) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ImageRepSkia() { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Width() const OVERRIDE { 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return image_->width(); 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Height() const OVERRIDE { 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return image_->height(); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual gfx::Size Size() const OVERRIDE { 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return image_->size(); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkia* image() { return image_.get(); } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ImageSkia> image_; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageRepSkia); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoaTouch : public ImageRep { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ImageRepCocoaTouch(UIImage* image) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ImageRep(Image::kImageRepCocoaTouch), 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_(image) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(image); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ImageRepCocoaTouch() { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::NSObjectRelease(image_); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_ = nil; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual int Width() const OVERRIDE { 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Size().width(); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual int Height() const OVERRIDE { 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Size().height(); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual gfx::Size Size() const OVERRIDE { 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return internal::UIImageSize(image_); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UIImage* image() const { return image_; } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UIImage* image_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageRepCocoaTouch); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoa : public ImageRep { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ImageRepCocoa(NSImage* image) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ImageRep(Image::kImageRepCocoa), 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_(image) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(image); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ImageRepCocoa() { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::NSObjectRelease(image_); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_ = nil; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Width() const OVERRIDE { 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Size().width(); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int Height() const OVERRIDE { 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Size().height(); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual gfx::Size Size() const OVERRIDE { 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return internal::NSImageSize(image_); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSImage* image() const { return image_; } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSImage* image_; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageRepCocoa); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_MACOSX) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Storage class acts similarly to the pixels in a SkBitmap: the Image 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class holds a refptr instance of Storage, which in turn holds all the 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageReps. This way, the Image can be cheaply copied. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageStorage : public base::RefCounted<ImageStorage> { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ImageStorage(Image::RepresentationType default_type) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : default_representation_type_(default_type), 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX) && !defined(OS_IOS) 369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default_representation_color_space_( 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::mac::GetGenericRGBColorSpace()), 371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif // defined(OS_MACOSX) && !defined(OS_IOS) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representations_deleter_(&representations_) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) Image::RepresentationType default_representation_type() { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_representation_type_; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) Image::RepresentationMap& representations() { return representations_; } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX) && !defined(OS_IOS) 381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void set_default_representation_color_space(CGColorSpaceRef color_space) { 382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default_representation_color_space_ = color_space; 383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CGColorSpaceRef default_representation_color_space() { 385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return default_representation_color_space_; 386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif // defined(OS_MACOSX) && !defined(OS_IOS) 388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<ImageStorage>; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ImageStorage() {} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The type of image that was passed to the constructor. This key will always 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exist in the |representations_| map. 3966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) Image::RepresentationType default_representation_type_; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX) && !defined(OS_IOS) 399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The default representation's colorspace. This is used for converting to 400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // NSImage. This field exists to compensate for PNGCodec not writing or 401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // reading colorspace ancillary chunks. (sRGB, iCCP). 402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Not owned. 403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CGColorSpaceRef default_representation_color_space_; 404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif // defined(OS_MACOSX) && !defined(OS_IOS) 405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All the representations of an Image. Size will always be at least one, with 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more for any converted representations. 4086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) Image::RepresentationMap representations_; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLValueDeleter<Image::RepresentationMap> representations_deleter_; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageStorage); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image() { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |storage_| is NULL for empty Images. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Image::Image(const std::vector<ImagePNGRep>& image_reps) { 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do not store obviously invalid ImagePNGReps. 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ImagePNGRep> filtered; 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < image_reps.size(); ++i) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (image_reps[i].raw_data.get() && image_reps[i].raw_data->size()) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) filtered.push_back(image_reps[i]); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (filtered.empty()) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_ = new internal::ImageStorage(Image::kImageRepPNG); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::ImageRepPNG* rep = new internal::ImageRepPNG(filtered); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRepresentation(rep); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(const ImageSkia& image) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!image.isNull()) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = new internal::ImageStorage(Image::kImageRepSkia); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepSkia* rep = new internal::ImageRepSkia( 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ImageSkia(image)); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRepresentation(rep); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(UIImage* image) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : storage_(new internal::ImageStorage(Image::kImageRepCocoaTouch)) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepCocoaTouch* rep = new internal::ImageRepCocoaTouch(image); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRepresentation(rep); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(NSImage* image) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = new internal::ImageStorage(Image::kImageRepCocoa); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepCocoa* rep = new internal::ImageRepCocoa(image); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRepresentation(rep); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(const Image& other) : storage_(other.storage_) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image& Image::operator=(const Image& other) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = other.storage_; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::~Image() { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Image Image::CreateFrom1xBitmap(const SkBitmap& bitmap) { 4776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return Image(ImageSkia::CreateFrom1xBitmap(bitmap)); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Image Image::CreateFrom1xPNGBytes(const unsigned char* input, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t input_size) { 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (input_size == 0u) 4846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return Image(); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedBytes> raw_data(new base::RefCountedBytes()); 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_data->data().assign(input, input + input_size); 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return CreateFrom1xPNGBytes(raw_data); 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Image Image::CreateFrom1xPNGBytes( 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::RefCountedMemory>& input) { 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!input.get() || input->size() == 0u) 4956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return Image(); 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) std::vector<ImagePNGRep> image_reps; 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) image_reps.push_back(ImagePNGRep(input, 1.0f)); 4996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return Image(image_reps); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkBitmap* Image::ToSkBitmap() const { 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possibly create and cache an intermediate ImageRepSkia. 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ToImageSkia()->bitmap(); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ImageSkia* Image::ToImageSkia() const { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRep* rep = GetRepresentation(kImageRepSkia, false); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rep) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (DefaultRepresentationType()) { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kImageRepPNG: { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepPNG* png_rep = 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep = new internal::ImageRepSkia( 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::ImageSkiaFromPNG(png_rep->image_reps())); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 518a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_IOS) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kImageRepCocoaTouch: { 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepCocoaTouch* native_rep = 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRepresentation(kImageRepCocoaTouch, true) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ->AsImageRepCocoaTouch(); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep = new internal::ImageRepSkia(new ImageSkia( 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkiaFromUIImage(native_rep->image()))); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kImageRepCocoa: { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepCocoa* native_rep = 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa(); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep = new internal::ImageRepSkia(new ImageSkia( 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkiaFromNSImage(native_rep->image()))); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(rep); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRepresentation(rep); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rep->AsImageRepSkia()->image(); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UIImage* Image::ToUIImage() const { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRep* rep = GetRepresentation(kImageRepCocoaTouch, false); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rep) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (DefaultRepresentationType()) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kImageRepPNG: { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepPNG* png_rep = 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep = new internal::ImageRepCocoaTouch(internal::CreateUIImageFromPNG( 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) png_rep->image_reps())); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kImageRepSkia: { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepSkia* skia_rep = 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UIImage* image = UIImageFromImageSkia(*skia_rep->image()); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::NSObjectRetain(image); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep = new internal::ImageRepCocoaTouch(image); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(rep); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRepresentation(rep); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rep->AsImageRepCocoaTouch()->image(); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSImage* Image::ToNSImage() const { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rep) { 577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CGColorSpaceRef default_representation_color_space = 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch storage_->default_representation_color_space(); 579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (DefaultRepresentationType()) { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kImageRepPNG: { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepPNG* png_rep = 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep = new internal::ImageRepCocoa(internal::NSImageFromPNG( 585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch png_rep->image_reps(), default_representation_color_space)); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kImageRepSkia: { 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRepSkia* skia_rep = 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); 591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NSImage* image = NSImageFromImageSkiaWithColorSpace(*skia_rep->image(), 592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default_representation_color_space); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::NSObjectRetain(image); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep = new internal::ImageRepCocoa(image); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(rep); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRepresentation(rep); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rep->AsImageRepCocoa()->image(); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Image::As1xPNGBytes() const { 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsEmpty()) 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new base::RefCountedBytes(); 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::ImageRep* rep = GetRepresentation(kImageRepPNG, false); 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rep) { 6146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const std::vector<ImagePNGRep>& image_png_reps = 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rep->AsImageRepPNG()->image_reps(); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < image_png_reps.size(); ++i) { 61768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (image_png_reps[i].scale == 1.0f) 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return image_png_reps[i].raw_data; 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new base::RefCountedBytes(); 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedMemory> png_bytes(NULL); 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (DefaultRepresentationType()) { 625a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_IOS) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kImageRepCocoaTouch: { 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::ImageRepCocoaTouch* cocoa_touch_rep = 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRepresentation(kImageRepCocoaTouch, true) 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ->AsImageRepCocoaTouch(); 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) png_bytes = internal::Get1xPNGBytesFromUIImage( 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cocoa_touch_rep->image()); 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_MACOSX) 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kImageRepCocoa: { 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::ImageRepCocoa* cocoa_rep = 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa(); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) png_bytes = internal::Get1xPNGBytesFromNSImage(cocoa_rep->image()); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kImageRepSkia: { 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::ImageRepSkia* skia_rep = 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) png_bytes = internal::Get1xPNGBytesFromImageSkia(skia_rep->image()); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!png_bytes.get() || !png_bytes->size()) { 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add an ImageRepPNG with no data such that the conversion is not 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // attempted each time we want the PNG bytes. 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddRepresentation(new internal::ImageRepPNG()); 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new base::RefCountedBytes(); 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do not insert representations for scale factors other than 1x even if 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // they are available because: 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - Only the 1x PNG bytes can be accessed. 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - ImageRepPNG is not used as an intermediate type in converting to a 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // final type eg (converting from ImageRepSkia to ImageRepPNG to get an 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ImageRepCocoa). 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ImagePNGRep> image_png_reps; 6656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) image_png_reps.push_back(ImagePNGRep(png_bytes, 1.0f)); 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rep = new internal::ImageRepPNG(image_png_reps); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddRepresentation(rep); 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return png_bytes; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap Image::AsBitmap() const { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsEmpty() ? SkBitmap() : *ToSkBitmap(); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageSkia Image::AsImageSkia() const { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsEmpty() ? ImageSkia() : *ToImageSkia(); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) && !defined(OS_IOS) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSImage* Image::AsNSImage() const { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsEmpty() ? nil : ToNSImage(); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Image::Copy1xPNGBytes() const { 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedMemory> original = As1xPNGBytes(); 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedBytes> copy(new base::RefCountedBytes()); 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) copy->data().assign(original->front(), original->front() + original->size()); 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return copy; 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageSkia* Image::CopyImageSkia() const { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ImageSkia(*ToImageSkia()); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap* Image::CopySkBitmap() const { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SkBitmap(*ToSkBitmap()); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UIImage* Image::CopyUIImage() const { 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UIImage* image = ToUIImage(); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::NSObjectRetain(image); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSImage* Image::CopyNSImage() const { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSImage* image = ToNSImage(); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::NSObjectRetain(image); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Image::HasRepresentation(RepresentationType type) const { 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return storage_.get() && storage_->representations().count(type) != 0; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t Image::RepresentationCount() const { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!storage_.get()) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return storage_->representations().size(); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Image::IsEmpty() const { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RepresentationCount() == 0; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int Image::Width() const { 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsEmpty()) 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetRepresentation(DefaultRepresentationType(), true)->Width(); 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int Image::Height() const { 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsEmpty()) 737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetRepresentation(DefaultRepresentationType(), true)->Height(); 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Size Image::Size() const { 742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsEmpty()) 743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return gfx::Size(); 744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetRepresentation(DefaultRepresentationType(), true)->Size(); 745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void Image::SwapRepresentations(Image* other) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_.swap(other->storage_); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX) && !defined(OS_IOS) 752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid Image::SetSourceColorSpace(CGColorSpaceRef color_space) { 753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (storage_.get()) 754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch storage_->set_default_representation_color_space(color_space); 755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif // defined(OS_MACOSX) && !defined(OS_IOS) 757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::RepresentationType Image::DefaultRepresentationType() const { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(storage_.get()); 760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return storage_->default_representation_type(); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)internal::ImageRep* Image::GetRepresentation( 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RepresentationType rep_type, bool must_exist) const { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(storage_.get()); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RepresentationMap::iterator it = storage_->representations().find(rep_type); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == storage_->representations().end()) { 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!must_exist); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return it->second; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Image::AddRepresentation(internal::ImageRep* rep) const { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(storage_.get()); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->representations().insert(std::make_pair(rep->type(), rep)); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 780