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)
32typedef struct CGColorSpace* CGColorSpaceRef;
33#endif
34
35class SkBitmap;
36
37namespace {
38class ImageTest;
39class ImageMacTest;
40}
41
42namespace gfx {
43struct ImagePNGRep;
44class ImageSkia;
45class Size;
46
47namespace internal {
48class ImageRep;
49class ImageStorage;
50}
51
52class GFX_EXPORT Image {
53 public:
54  enum RepresentationType {
55    kImageRepCocoa,
56    kImageRepCocoaTouch,
57    kImageRepSkia,
58    kImageRepPNG,
59  };
60
61  typedef std::map<RepresentationType, internal::ImageRep*> RepresentationMap;
62
63  // Creates an empty image with no representations.
64  Image();
65
66  // Creates a new image by copying the raw PNG-encoded input for use as the
67  // default representation.
68  explicit Image(const std::vector<ImagePNGRep>& image_reps);
69
70  // Creates a new image by copying the ImageSkia for use as the default
71  // representation.
72  explicit Image(const ImageSkia& image);
73
74#if defined(OS_IOS)
75  // Does not retain |image|; expects to take ownership.
76  explicit Image(UIImage* image);
77#elif defined(OS_MACOSX)
78  // Does not retain |image|; expects to take ownership.
79  // A single NSImage object can contain multiple bitmaps so there's no reason
80  // to pass a vector of these.
81  explicit Image(NSImage* image);
82#endif
83
84  // Initializes a new Image by AddRef()ing |other|'s internal storage.
85  Image(const Image& other);
86
87  // Copies a reference to |other|'s storage.
88  Image& operator=(const Image& other);
89
90  // Deletes the image and, if the only owner of the storage, all of its cached
91  // representations.
92  ~Image();
93
94  // Creates an image from the passed in 1x bitmap.
95  // WARNING: The resulting image will be pixelated when painted on a high
96  // density display.
97  static Image CreateFrom1xBitmap(const SkBitmap& bitmap);
98
99  // Creates an image from the PNG encoded input.
100  // For example (from an std::vector):
101  // std::vector<unsigned char> png = ...;
102  // gfx::Image image =
103  //     Image::CreateFrom1xPNGBytes(&png.front(), png.size());
104  static Image CreateFrom1xPNGBytes(const unsigned char* input,
105                                    size_t input_size);
106
107  // Creates an image from the PNG encoded input.
108  static Image CreateFrom1xPNGBytes(
109      const scoped_refptr<base::RefCountedMemory>& input);
110
111  // Converts the Image to the desired representation and stores it internally.
112  // The returned result is a weak pointer owned by and scoped to the life of
113  // the Image. Must only be called if IsEmpty() is false.
114  const SkBitmap* ToSkBitmap() const;
115  const ImageSkia* ToImageSkia() const;
116#if defined(OS_IOS)
117  UIImage* ToUIImage() const;
118#elif defined(OS_MACOSX)
119  NSImage* ToNSImage() const;
120#endif
121
122  // Returns the raw PNG-encoded data for the bitmap at 1x. If the data is
123  // unavailable, either because the image has no data for 1x or because it is
124  // empty, an empty RefCountedBytes object is returned. NULL is never
125  // returned.
126  scoped_refptr<base::RefCountedMemory> As1xPNGBytes() const;
127
128  // Same as ToSkBitmap(), but returns a null SkBitmap if this image is empty.
129  SkBitmap AsBitmap() const;
130
131  // Same as ToImageSkia(), but returns an empty ImageSkia if this
132  // image is empty.
133  ImageSkia AsImageSkia() const;
134
135#if defined(OS_MACOSX) && !defined(OS_IOS)
136  // Same as ToSkBitmap(), but returns nil if this image is empty.
137  NSImage* AsNSImage() const;
138#endif
139
140  // Performs a conversion, like above, but returns a copy of the result rather
141  // than a weak pointer. The caller is responsible for deleting the result.
142  // Note that the result is only a copy in terms of memory management; the
143  // backing pixels are shared amongst all copies (a fact of each of the
144  // converted representations, rather than a limitation imposed by Image) and
145  // so the result should be considered immutable.
146  scoped_refptr<base::RefCountedMemory> Copy1xPNGBytes() const;
147  ImageSkia* CopyImageSkia() const;
148  SkBitmap* CopySkBitmap() const;
149#if defined(OS_IOS)
150  UIImage* CopyUIImage() const;
151#elif defined(OS_MACOSX)
152  NSImage* CopyNSImage() const;
153#endif
154
155  // Inspects the representations map to see if the given type exists.
156  bool HasRepresentation(RepresentationType type) const;
157
158  // Returns the number of representations.
159  size_t RepresentationCount() const;
160
161  // Returns true if this Image has no representations.
162  bool IsEmpty() const;
163
164  // Width and height of image in DIP coordinate system.
165  int Width() const;
166  int Height() const;
167  gfx::Size Size() const;
168
169  // Swaps this image's internal representations with |other|.
170  void SwapRepresentations(gfx::Image* other);
171
172#if defined(OS_MACOSX) && !defined(OS_IOS)
173  // Set the default representation's color space. This is used for converting
174  // to NSImage. This is used to compensate for PNGCodec not writing or reading
175  // colorspace ancillary chunks. (sRGB, iCCP).
176  void SetSourceColorSpace(CGColorSpaceRef color_space);
177#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
178
179 private:
180  // Returns the type of the default representation.
181  RepresentationType DefaultRepresentationType() const;
182
183  // Returns the ImageRep of the appropriate type or NULL if there is no
184  // representation of that type (and must_exist is false).
185  internal::ImageRep* GetRepresentation(
186      RepresentationType rep_type, bool must_exist) const;
187
188  // Stores a representation into the map.
189  void AddRepresentation(internal::ImageRep* rep) const;
190
191  // Internal class that holds all the representations. This allows the Image to
192  // be cheaply copied.
193  scoped_refptr<internal::ImageStorage> storage_;
194
195  friend class ::ImageTest;
196  friend class ::ImageMacTest;
197};
198
199}  // namespace gfx
200
201#endif  // UI_GFX_IMAGE_IMAGE_H_
202