SkImage.h revision 9e447c08deb30b26a2101cb20b8a04aa230f09c4
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    int width() const { return fWidth; }
68    int height() const { return fHeight; }
69    uint32_t uniqueID() const { return fUniqueID; }
70    virtual bool isOpaque() const { return false; }
71
72    /**
73     * Return the GrTexture that stores the image pixels. Calling getTexture
74     * does not affect the reference count of the GrTexture object.
75     * Will return NULL if the image does not use a texture.
76     */
77    GrTexture* getTexture();
78
79    virtual SkShader* newShader(SkShader::TileMode,
80                                SkShader::TileMode,
81                                const SkMatrix* localMatrix = NULL) const;
82
83    /**
84     *  If the image has direct access to its pixels (i.e. they are in local
85     *  RAM) return the (const) address of those pixels, and if not null, return
86     *  the ImageInfo and rowBytes. The returned address is only valid while
87     *  the image object is in scope.
88     *
89     *  On failure, returns NULL and the info and rowBytes parameters are
90     *  ignored.
91     */
92    const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const;
93
94    /**
95     *  Copy the pixels from the image into the specified buffer (pixels + rowBytes),
96     *  converting them into the requested format (dstInfo). The image pixels are read
97     *  starting at the specified (srcX,srcY) location.
98     *
99     *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
100     *
101     *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
102     *
103     *  srcR is intersected with the bounds of the image. If this intersection is not empty,
104     *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
105     *  corresponding src pixels, performing any colortype/alphatype transformations needed
106     *  (in the case where the src and dst have different colortypes or alphatypes).
107     *
108     *  This call can fail, returning false, for several reasons:
109     *  - If srcR does not intersect the image bounds.
110     *  - If the requested colortype/alphatype cannot be converted from the image's types.
111     */
112    bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
113                    int srcX, int srcY) const;
114
115    /**
116     *  Encode the image's pixels and return the result as a new SkData, which
117     *  the caller must manage (i.e. call unref() when they are done).
118     *
119     *  If the image type cannot be encoded, or the requested encoder type is
120     *  not supported, this will return NULL.
121     */
122    SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type,
123                   int quality = 80) const;
124
125    /**
126     *  Return a new surface that is compatible with this image's internal representation
127     *  (e.g. raster or gpu).
128     *
129     *  If no surfaceprops are specified, the image will attempt to match the props of when it
130     *  was created (if it came from a surface).
131     */
132    SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL) const;
133
134    const char* toString(SkString*) const;
135
136    /**
137     *  Return an image that is a rescale of this image (using newWidth, newHeight).
138     *
139     *  If subset is NULL, then the entire original image is used as the src for the scaling.
140     *  If subset is not NULL, then it specifies subset of src-pixels used for scaling. If
141     *  subset extends beyond the bounds of the original image, then NULL is returned.
142     *
143     *  Notes:
144     *  - newWidth and newHeight must be > 0 or NULL will be returned.
145     *
146     *  - it is legal for the returned image to be the same instance as the src image
147     *    (if the new dimensions == the src dimensions and subset is NULL or == src dimensions).
148     *
149     *  - it is legal for the "scaled" image to have changed its SkAlphaType from unpremul
150     *    to premul (as required by the impl). The image should draw (nearly) identically,
151     *    since during drawing we will "apply the alpha" to the pixels. Future optimizations
152     *    may take away this caveat, preserving unpremul.
153     */
154    SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset = NULL,
155                      SkFilterQuality = kNone_SkFilterQuality) const;
156
157protected:
158    SkImage(int width, int height) :
159        fWidth(width),
160        fHeight(height),
161        fUniqueID(NextUniqueID()) {
162
163        SkASSERT(width > 0);
164        SkASSERT(height > 0);
165    }
166
167private:
168    const int       fWidth;
169    const int       fHeight;
170    const uint32_t  fUniqueID;
171
172    static uint32_t NextUniqueID();
173
174    typedef SkRefCnt INHERITED;
175
176    friend class SkCanvas;
177
178    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
179
180    /**
181     *  Draw the image, cropped to the src rect, to the dst rect of a canvas.
182     *  If src is larger than the bounds of the image, the rest of the image is
183     *  filled with transparent black pixels.
184     *
185     *  See SkCanvas::drawBitmapRectToRect for similar behavior.
186     */
187    void drawRect(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) const;
188};
189
190#endif
191