SkImage.h revision 8b26b99c97473f020df4b9d4ba789e074e06cedd
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    int width() const { return fWidth; }
86    int height() const { return fHeight; }
87    uint32_t uniqueID() const { return fUniqueID; }
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
175protected:
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
185private:
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