• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gfx/gfx_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 GFX_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