1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkImage_DEFINED
9 #define SkImage_DEFINED
10 
11 #include "SkFilterQuality.h"
12 #include "SkImageInfo.h"
13 #include "SkImageEncoder.h"
14 #include "SkRefCnt.h"
15 #include "SkScalar.h"
16 #include "SkShader.h"
17 
18 class SkData;
19 class SkCanvas;
20 class SkImageGenerator;
21 class SkPaint;
22 class SkString;
23 class SkSurface;
24 class SkSurfaceProps;
25 class GrContext;
26 class GrTexture;
27 
28 /**
29  *  SkImage is an abstraction for drawing a rectagle of pixels, though the
30  *  particular type of image could be actually storing its data on the GPU, or
31  *  as drawing commands (picture or PDF or otherwise), ready to be played back
32  *  into another canvas.
33  *
34  *  The content of SkImage is always immutable, though the actual storage may
35  *  change, if for example that image can be re-created via encoded data or
36  *  other means.
37  *
38  *  SkImage always has a non-zero dimensions. If there is a request to create a new image, either
39  *  directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be
40  *  returned.
41  */
42 class SK_API SkImage : public SkRefCnt {
43 public:
44     SK_DECLARE_INST_COUNT(SkImage)
45 
46     typedef SkImageInfo Info;
47 
48     static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes);
49     static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
50 
51     /**
52      *  Construct a new SkImage based on the given ImageGenerator.
53      *  This function will always take ownership of the passed
54      *  ImageGenerator.  Returns NULL on error.
55      */
56     static SkImage* NewFromGenerator(SkImageGenerator*);
57 
58     /**
59      *  Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
60      *  which can mean that the format of the encoded data was not recognized/supported.
61      *
62      *  Regardless of success or failure, the caller is responsible for managing their ownership
63      *  of the data.
64      */
65     static SkImage* NewFromData(SkData* data);
66 
67     /**
68      *  Create a new image from the specified descriptor. Note - the caller is responsible for
69      *  managing the lifetime of the underlying platform texture.
70      *
71      *  Will return NULL if the specified descriptor is unsupported.
72      */
73     static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&,
74                                    SkAlphaType = kPremul_SkAlphaType);
75 
76     /**
77      *  Create a new image by copying the pixels from the specified descriptor. No reference is
78      *  kept to the original platform texture.
79      *
80      *  Will return NULL if the specified descriptor is unsupported.
81      */
82     static SkImage* NewFromTextureCopy(GrContext*, const GrBackendTextureDesc&,
83                                        SkAlphaType = kPremul_SkAlphaType);
84 
width()85     int width() const { return fWidth; }
height()86     int height() const { return fHeight; }
uniqueID()87     uint32_t uniqueID() const { return fUniqueID; }
isOpaque()88     virtual bool isOpaque() const { return false; }
89 
90     /**
91      * Return the GrTexture that stores the image pixels. Calling getTexture
92      * does not affect the reference count of the GrTexture object.
93      * Will return NULL if the image does not use a texture.
94      */
95     GrTexture* getTexture() const;
96 
97     virtual SkShader* newShader(SkShader::TileMode,
98                                 SkShader::TileMode,
99                                 const SkMatrix* localMatrix = NULL) const;
100 
101     /**
102      *  If the image has direct access to its pixels (i.e. they are in local
103      *  RAM) return the (const) address of those pixels, and if not null, return
104      *  the ImageInfo and rowBytes. The returned address is only valid while
105      *  the image object is in scope.
106      *
107      *  On failure, returns NULL and the info and rowBytes parameters are
108      *  ignored.
109      */
110     const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const;
111 
112     /**
113      *  Copy the pixels from the image into the specified buffer (pixels + rowBytes),
114      *  converting them into the requested format (dstInfo). The image pixels are read
115      *  starting at the specified (srcX,srcY) location.
116      *
117      *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
118      *
119      *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
120      *
121      *  srcR is intersected with the bounds of the image. If this intersection is not empty,
122      *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
123      *  corresponding src pixels, performing any colortype/alphatype transformations needed
124      *  (in the case where the src and dst have different colortypes or alphatypes).
125      *
126      *  This call can fail, returning false, for several reasons:
127      *  - If srcR does not intersect the image bounds.
128      *  - If the requested colortype/alphatype cannot be converted from the image's types.
129      */
130     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
131                     int srcX, int srcY) const;
132 
133     /**
134      *  Encode the image's pixels and return the result as a new SkData, which
135      *  the caller must manage (i.e. call unref() when they are done).
136      *
137      *  If the image type cannot be encoded, or the requested encoder type is
138      *  not supported, this will return NULL.
139      */
140     SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type,
141                    int quality = 80) const;
142 
143     /**
144      *  Return a new surface that is compatible with this image's internal representation
145      *  (e.g. raster or gpu).
146      *
147      *  If no surfaceprops are specified, the image will attempt to match the props of when it
148      *  was created (if it came from a surface).
149      */
150     SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL) const;
151 
152     const char* toString(SkString*) const;
153 
154     /**
155      *  Return an image that is a rescale of this image (using newWidth, newHeight).
156      *
157      *  If subset is NULL, then the entire original image is used as the src for the scaling.
158      *  If subset is not NULL, then it specifies subset of src-pixels used for scaling. If
159      *  subset extends beyond the bounds of the original image, then NULL is returned.
160      *
161      *  Notes:
162      *  - newWidth and newHeight must be > 0 or NULL will be returned.
163      *
164      *  - it is legal for the returned image to be the same instance as the src image
165      *    (if the new dimensions == the src dimensions and subset is NULL or == src dimensions).
166      *
167      *  - it is legal for the "scaled" image to have changed its SkAlphaType from unpremul
168      *    to premul (as required by the impl). The image should draw (nearly) identically,
169      *    since during drawing we will "apply the alpha" to the pixels. Future optimizations
170      *    may take away this caveat, preserving unpremul.
171      */
172     SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset = NULL,
173                       SkFilterQuality = kNone_SkFilterQuality) const;
174 
175 protected:
SkImage(int width,int height)176     SkImage(int width, int height) :
177         fWidth(width),
178         fHeight(height),
179         fUniqueID(NextUniqueID()) {
180 
181         SkASSERT(width > 0);
182         SkASSERT(height > 0);
183     }
184 
185 private:
186     const int       fWidth;
187     const int       fHeight;
188     const uint32_t  fUniqueID;
189 
190     static uint32_t NextUniqueID();
191 
192     typedef SkRefCnt INHERITED;
193 };
194 
195 #endif
196