SkImage.h revision 55812362f1df3c1f7341f687d5bab0adab8ac954
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
18class SkData;
19class SkCanvas;
20class SkImageGenerator;
21class SkPaint;
22class SkString;
23class SkSurface;
24class SkSurfaceProps;
25class GrContext;
26class 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 */
42class SK_API SkImage : public SkRefCnt {
43public:
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
85    /**
86     *  Create a new image by copying the pixels from the specified y, u, v textures. The data
87     *  from the textures is immediately ingested into the image and the textures can be modified or
88     *  deleted after the function returns. The image will have the dimensions of the y texture.
89     */
90    static SkImage* NewFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
91                                           const GrBackendObject yuvTextureHandles[3],
92                                           const SkISize yuvSizes[3],
93                                           GrSurfaceOrigin);
94
95    int width() const { return fWidth; }
96    int height() const { return fHeight; }
97    uint32_t uniqueID() const { return fUniqueID; }
98    virtual bool isOpaque() const { return false; }
99
100    virtual SkShader* newShader(SkShader::TileMode,
101                                SkShader::TileMode,
102                                const SkMatrix* localMatrix = NULL) const;
103
104    /**
105     *  If the image has direct access to its pixels (i.e. they are in local
106     *  RAM) return the (const) address of those pixels, and if not null, return
107     *  the ImageInfo and rowBytes. The returned address is only valid while
108     *  the image object is in scope.
109     *
110     *  On failure, returns NULL and the info and rowBytes parameters are
111     *  ignored.
112     */
113    const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const;
114
115    // DEPRECATED
116    GrTexture* getTexture() const;
117
118    /**
119     *  Returns true if the image is texture backed.
120     */
121    bool isTextureBacked() const;
122
123    /**
124     *  Retrieves the backend API handle of the texture. If flushPendingGrContextReads then the
125     *  GrContext will issue to the backend API any deferred read operations on the texture before
126     *  returning.
127     */
128    GrBackendObject getTextureHandle(bool flushPendingGrContextReads) const;
129
130    /**
131     *  Copy the pixels from the image into the specified buffer (pixels + rowBytes),
132     *  converting them into the requested format (dstInfo). The image pixels are read
133     *  starting at the specified (srcX,srcY) location.
134     *
135     *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
136     *
137     *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
138     *
139     *  srcR is intersected with the bounds of the image. If this intersection is not empty,
140     *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
141     *  corresponding src pixels, performing any colortype/alphatype transformations needed
142     *  (in the case where the src and dst have different colortypes or alphatypes).
143     *
144     *  This call can fail, returning false, for several reasons:
145     *  - If srcR does not intersect the image bounds.
146     *  - If the requested colortype/alphatype cannot be converted from the image's types.
147     */
148    bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
149                    int srcX, int srcY) const;
150
151    /**
152     *  Encode the image's pixels and return the result as a new SkData, which
153     *  the caller must manage (i.e. call unref() when they are done).
154     *
155     *  If the image type cannot be encoded, or the requested encoder type is
156     *  not supported, this will return NULL.
157     */
158    SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type,
159                   int quality = 80) const;
160
161    /**
162     *  Return a new surface that is compatible with this image's internal representation
163     *  (e.g. raster or gpu).
164     *
165     *  If no surfaceprops are specified, the image will attempt to match the props of when it
166     *  was created (if it came from a surface).
167     */
168    SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL) const;
169
170    const char* toString(SkString*) const;
171
172    /**
173     *  Return an image that is a rescale of this image (using newWidth, newHeight).
174     *
175     *  If subset is NULL, then the entire original image is used as the src for the scaling.
176     *  If subset is not NULL, then it specifies subset of src-pixels used for scaling. If
177     *  subset extends beyond the bounds of the original image, then NULL is returned.
178     *
179     *  Notes:
180     *  - newWidth and newHeight must be > 0 or NULL will be returned.
181     *
182     *  - it is legal for the returned image to be the same instance as the src image
183     *    (if the new dimensions == the src dimensions and subset is NULL or == src dimensions).
184     *
185     *  - it is legal for the "scaled" image to have changed its SkAlphaType from unpremul
186     *    to premul (as required by the impl). The image should draw (nearly) identically,
187     *    since during drawing we will "apply the alpha" to the pixels. Future optimizations
188     *    may take away this caveat, preserving unpremul.
189     */
190    SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset = NULL,
191                      SkFilterQuality = kNone_SkFilterQuality) const;
192
193protected:
194    SkImage(int width, int height) :
195        fWidth(width),
196        fHeight(height),
197        fUniqueID(NextUniqueID()) {
198
199        SkASSERT(width > 0);
200        SkASSERT(height > 0);
201    }
202
203private:
204    const int       fWidth;
205    const int       fHeight;
206    const uint32_t  fUniqueID;
207
208    static uint32_t NextUniqueID();
209
210    typedef SkRefCnt INHERITED;
211};
212
213#endif
214