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)// An Image wraps an image any flavor, be it platform-native GdkBitmap/NSImage, 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or a SkBitmap. This also provides easy conversion to other image types 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through operator overloading. It will cache the converted representations 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// internally to prevent double-conversion. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The lifetime of both the initial representation and any converted ones are 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tied to the lifetime of the Image's internal storage. To allow Images to be 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cheaply passed around by value, the actual image data is stored in a ref- 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// counted member. When all Images referencing this storage are deleted, the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// actual representations are deleted, too. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Images can be empty, in which case they have no backing representation. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Attempting to use an empty Image will result in a crash. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_GFX_IMAGE_IMAGE_H_ 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_GFX_IMAGE_IMAGE_H_ 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted_memory.h" 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/gfx_export.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX) && !defined(OS_IOS) 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef struct CGColorSpace* CGColorSpaceRef; 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SkBitmap; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageTest; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageMacTest; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ImagePNGRep; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageSkia; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class Size; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRep; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageStorage; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class GFX_EXPORT Image { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum RepresentationType { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImageRepCocoa, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImageRepCocoaTouch, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImageRepSkia, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImageRepPNG, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<RepresentationType, internal::ImageRep*> RepresentationMap; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an empty image with no representations. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Image(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates a new image by copying the raw PNG-encoded input for use as the 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // default representation. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit Image(const std::vector<ImagePNGRep>& image_reps); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new image by copying the ImageSkia for use as the default 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // representation. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Image(const ImageSkia& image); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_IOS) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does not retain |image|; expects to take ownership. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Image(UIImage* image); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does not retain |image|; expects to take ownership. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A single NSImage object can contain multiple bitmaps so there's no reason 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to pass a vector of these. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Image(NSImage* image); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes a new Image by AddRef()ing |other|'s internal storage. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Image(const Image& other); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copies a reference to |other|'s storage. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Image& operator=(const Image& other); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the image and, if the only owner of the storage, all of its cached 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // representations. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Image(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates an image from the passed in 1x bitmap. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WARNING: The resulting image will be pixelated when painted on a high 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // density display. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static Image CreateFrom1xBitmap(const SkBitmap& bitmap); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates an image from the PNG encoded input. 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For example (from an std::vector): 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // std::vector<unsigned char> png = ...; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // gfx::Image image = 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Image::CreateFrom1xPNGBytes(&png.front(), png.size()); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static Image CreateFrom1xPNGBytes(const unsigned char* input, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t input_size); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Creates an image from the PNG encoded input. 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static Image CreateFrom1xPNGBytes( 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::RefCountedMemory>& input); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Converts the Image to the desired representation and stores it internally. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The returned result is a weak pointer owned by and scoped to the life of 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Image. Must only be called if IsEmpty() is false. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap* ToSkBitmap() const; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ImageSkia* ToImageSkia() const; 116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_IOS) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UIImage* ToUIImage() const; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSImage* ToNSImage() const; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns the raw PNG-encoded data for the bitmap at 1x. If the data is 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unavailable, either because the image has no data for 1x or because it is 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // empty, an empty RefCountedBytes object is returned. NULL is never 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // returned. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedMemory> As1xPNGBytes() const; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as ToSkBitmap(), but returns a null SkBitmap if this image is empty. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap AsBitmap() const; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as ToImageSkia(), but returns an empty ImageSkia if this 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // image is empty. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkia AsImageSkia() const; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) && !defined(OS_IOS) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as ToSkBitmap(), but returns nil if this image is empty. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSImage* AsNSImage() const; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs a conversion, like above, but returns a copy of the result rather 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // than a weak pointer. The caller is responsible for deleting the result. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the result is only a copy in terms of memory management; the 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // backing pixels are shared amongst all copies (a fact of each of the 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // converted representations, rather than a limitation imposed by Image) and 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so the result should be considered immutable. 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedMemory> Copy1xPNGBytes() const; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkia* CopyImageSkia() const; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap* CopySkBitmap() const; 149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_IOS) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UIImage* CopyUIImage() const; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSImage* CopyNSImage() const; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inspects the representations map to see if the given type exists. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasRepresentation(RepresentationType type) const; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of representations. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t RepresentationCount() const; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this Image has no representations. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsEmpty() const; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Width and height of image in DIP coordinate system. 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int Width() const; 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int Height() const; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Size Size() const; 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Swaps this image's internal representations with |other|. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SwapRepresentations(gfx::Image* other); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX) && !defined(OS_IOS) 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set the default representation's color space. This is used for converting 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // to NSImage. This is used to compensate for PNGCodec not writing or reading 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // colorspace ancillary chunks. (sRGB, iCCP). 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void SetSourceColorSpace(CGColorSpaceRef color_space); 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif // defined(OS_MACOSX) && !defined(OS_IOS) 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the type of the default representation. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RepresentationType DefaultRepresentationType() const; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the ImageRep of the appropriate type or NULL if there is no 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // representation of that type (and must_exist is false). 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ImageRep* GetRepresentation( 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RepresentationType rep_type, bool must_exist) const; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stores a representation into the map. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRepresentation(internal::ImageRep* rep) const; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Internal class that holds all the representations. This allows the Image to 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be cheaply copied. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<internal::ImageStorage> storage_; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ::ImageTest; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ::ImageMacTest; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // UI_GFX_IMAGE_IMAGE_H_ 202