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