Home | History | Annotate | Download | only in image
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // An Image wraps an image any flavor, be it platform-native GdkBitmap/NSImage,
      6 // or a SkBitmap. This also provides easy conversion to other image types
      7 // through operator overloading. It will cache the converted representations
      8 // internally to prevent double-conversion.
      9 //
     10 // The lifetime of both the initial representation and any converted ones are
     11 // tied to the lifetime of the Image's internal storage. To allow Images to be
     12 // cheaply passed around by value, the actual image data is stored in a ref-
     13 // counted member. When all Images referencing this storage are deleted, the
     14 // actual representations are deleted, too.
     15 //
     16 // Images can be empty, in which case they have no backing representation.
     17 // Attempting to use an empty Image will result in a crash.
     18 
     19 #ifndef UI_GFX_IMAGE_IMAGE_H_
     20 #define UI_GFX_IMAGE_IMAGE_H_
     21 
     22 #include <map>
     23 #include <vector>
     24 
     25 #include "base/basictypes.h"
     26 #include "base/gtest_prod_util.h"
     27 #include "base/memory/ref_counted_memory.h"
     28 #include "ui/base/ui_export.h"
     29 #include "ui/gfx/native_widget_types.h"
     30 
     31 #if defined(OS_MACOSX) && !defined(OS_IOS)
     32 typedef struct CGColorSpace* CGColorSpaceRef;
     33 #endif
     34 
     35 class SkBitmap;
     36 
     37 namespace {
     38 class ImageTest;
     39 class ImageMacTest;
     40 }
     41 
     42 namespace gfx {
     43 struct ImagePNGRep;
     44 class ImageSkia;
     45 class Size;
     46 
     47 #if defined(TOOLKIT_GTK)
     48 class CairoCachedSurface;
     49 #endif
     50 
     51 namespace internal {
     52 class ImageRep;
     53 class ImageStorage;
     54 }
     55 
     56 class UI_EXPORT Image {
     57  public:
     58   enum RepresentationType {
     59     kImageRepGdk,
     60     kImageRepCocoa,
     61     kImageRepCocoaTouch,
     62     kImageRepCairo,
     63     kImageRepSkia,
     64     kImageRepPNG,
     65   };
     66 
     67   typedef std::map<RepresentationType, internal::ImageRep*> RepresentationMap;
     68 
     69   // Creates an empty image with no representations.
     70   Image();
     71 
     72   // Creates a new image by copying the raw PNG-encoded input for use as the
     73   // default representation.
     74   explicit Image(const std::vector<ImagePNGRep>& image_reps);
     75 
     76   // Creates a new image by copying the ImageSkia for use as the default
     77   // representation.
     78   explicit Image(const ImageSkia& image);
     79 
     80 #if defined(TOOLKIT_GTK)
     81   // Does not increase |pixbuf|'s reference count; expects to take ownership.
     82   explicit Image(GdkPixbuf* pixbuf);
     83 #elif defined(OS_IOS)
     84   // Does not retain |image|; expects to take ownership.
     85   explicit Image(UIImage* image);
     86 #elif defined(OS_MACOSX)
     87   // Does not retain |image|; expects to take ownership.
     88   // A single NSImage object can contain multiple bitmaps so there's no reason
     89   // to pass a vector of these.
     90   explicit Image(NSImage* image);
     91 #endif
     92 
     93   // Initializes a new Image by AddRef()ing |other|'s internal storage.
     94   Image(const Image& other);
     95 
     96   // Copies a reference to |other|'s storage.
     97   Image& operator=(const Image& other);
     98 
     99   // Deletes the image and, if the only owner of the storage, all of its cached
    100   // representations.
    101   ~Image();
    102 
    103   // Creates an image from the passed in 1x bitmap.
    104   // WARNING: The resulting image will be pixelated when painted on a high
    105   // density display.
    106   static Image CreateFrom1xBitmap(const SkBitmap& bitmap);
    107 
    108   // Creates an image from the PNG encoded input.
    109   // For example (from an std::vector):
    110   // std::vector<unsigned char> png = ...;
    111   // gfx::Image image =
    112   //     Image::CreateFrom1xPNGBytes(&png.front(), png.size());
    113   static Image CreateFrom1xPNGBytes(const unsigned char* input,
    114                                     size_t input_size);
    115 
    116   // Converts the Image to the desired representation and stores it internally.
    117   // The returned result is a weak pointer owned by and scoped to the life of
    118   // the Image. Must only be called if IsEmpty() is false.
    119   const SkBitmap* ToSkBitmap() const;
    120   const ImageSkia* ToImageSkia() const;
    121 #if defined(TOOLKIT_GTK)
    122   GdkPixbuf* ToGdkPixbuf() const;
    123   CairoCachedSurface* const ToCairo() const;
    124 #elif defined(OS_IOS)
    125   UIImage* ToUIImage() const;
    126 #elif defined(OS_MACOSX)
    127   NSImage* ToNSImage() const;
    128 #endif
    129 
    130   // Returns the raw PNG-encoded data for the bitmap at 1x. If the data is
    131   // unavailable, either because the image has no data for 1x or because it is
    132   // empty, an empty RefCountedBytes object is returned. NULL is never
    133   // returned.
    134   scoped_refptr<base::RefCountedMemory> As1xPNGBytes() const;
    135 
    136   // Same as ToSkBitmap(), but returns a null SkBitmap if this image is empty.
    137   SkBitmap AsBitmap() const;
    138 
    139   // Same as ToImageSkia(), but returns an empty ImageSkia if this
    140   // image is empty.
    141   ImageSkia AsImageSkia() const;
    142 
    143 #if defined(OS_MACOSX) && !defined(OS_IOS)
    144   // Same as ToSkBitmap(), but returns nil if this image is empty.
    145   NSImage* AsNSImage() const;
    146 #endif
    147 
    148   // Performs a conversion, like above, but returns a copy of the result rather
    149   // than a weak pointer. The caller is responsible for deleting the result.
    150   // Note that the result is only a copy in terms of memory management; the
    151   // backing pixels are shared amongst all copies (a fact of each of the
    152   // converted representations, rather than a limitation imposed by Image) and
    153   // so the result should be considered immutable.
    154   scoped_refptr<base::RefCountedMemory> Copy1xPNGBytes() const;
    155   ImageSkia* CopyImageSkia() const;
    156   SkBitmap* CopySkBitmap() const;
    157 #if defined(TOOLKIT_GTK)
    158   GdkPixbuf* CopyGdkPixbuf() const;
    159 #elif defined(OS_IOS)
    160   UIImage* CopyUIImage() const;
    161 #elif defined(OS_MACOSX)
    162   NSImage* CopyNSImage() const;
    163 #endif
    164 
    165   // Inspects the representations map to see if the given type exists.
    166   bool HasRepresentation(RepresentationType type) const;
    167 
    168   // Returns the number of representations.
    169   size_t RepresentationCount() const;
    170 
    171   // Returns true if this Image has no representations.
    172   bool IsEmpty() const;
    173 
    174   // Width and height of image in DIP coordinate system.
    175   int Width() const;
    176   int Height() const;
    177   gfx::Size Size() const;
    178 
    179   // Swaps this image's internal representations with |other|.
    180   void SwapRepresentations(gfx::Image* other);
    181 
    182 #if defined(OS_MACOSX) && !defined(OS_IOS)
    183   // Set the default representation's color space. This is used for converting
    184   // to NSImage. This is used to compensate for PNGCodec not writing or reading
    185   // colorspace ancillary chunks. (sRGB, iCCP).
    186   void SetSourceColorSpace(CGColorSpaceRef color_space);
    187 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
    188 
    189  private:
    190   // Returns the type of the default representation.
    191   RepresentationType DefaultRepresentationType() const;
    192 
    193   // Returns the ImageRep of the appropriate type or NULL if there is no
    194   // representation of that type (and must_exist is false).
    195   internal::ImageRep* GetRepresentation(
    196       RepresentationType rep_type, bool must_exist) const;
    197 
    198   // Stores a representation into the map.
    199   void AddRepresentation(internal::ImageRep* rep) const;
    200 
    201   // Internal class that holds all the representations. This allows the Image to
    202   // be cheaply copied.
    203   scoped_refptr<internal::ImageStorage> storage_;
    204 
    205   friend class ::ImageTest;
    206   friend class ::ImageMacTest;
    207 };
    208 
    209 }  // namespace gfx
    210 
    211 #endif  // UI_GFX_IMAGE_IMAGE_H_
    212