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 SkColorTable;
21 class SkImageGenerator;
22 class SkPaint;
23 class SkPicture;
24 class SkPixelSerializer;
25 class SkString;
26 class SkSurface;
27 class GrContext;
28 class GrTexture;
29 
30 /**
31  *  SkImage is an abstraction for drawing a rectagle of pixels, though the
32  *  particular type of image could be actually storing its data on the GPU, or
33  *  as drawing commands (picture or PDF or otherwise), ready to be played back
34  *  into another canvas.
35  *
36  *  The content of SkImage is always immutable, though the actual storage may
37  *  change, if for example that image can be re-created via encoded data or
38  *  other means.
39  *
40  *  SkImage always has a non-zero dimensions. If there is a request to create a new image, either
41  *  directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be
42  *  returned.
43  */
44 class SK_API SkImage : public SkRefCnt {
45 public:
46     typedef SkImageInfo Info;
47     typedef void* ReleaseContext;
48 
49     static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes,
50                                   SkColorTable* ctable = NULL);
51     static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
52 
53     typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext);
54 
55     /**
56      *  Return a new Image referencing the specified pixels. These must remain valid and unchanged
57      *  until the specified release-proc is called, indicating that Skia no longer has a reference
58      *  to the pixels.
59      *
60      *  Returns NULL if the requested Info is unsupported.
61      */
62     static SkImage* NewFromRaster(const Info&, const void* pixels, size_t rowBytes,
63                                   RasterReleaseProc, ReleaseContext);
64 
65     /**
66      *  Construct a new image from the specified bitmap. If the bitmap is marked immutable, and
67      *  its pixel memory is shareable, it may be shared instead of copied.
68      */
69     static SkImage* NewFromBitmap(const SkBitmap&);
70 
71     /**
72      *  Construct a new SkImage based on the given ImageGenerator.
73      *  This function will always take ownership of the passed
74      *  ImageGenerator.  Returns NULL on error.
75      *
76      *  If a subset is specified, it must be contained within the generator's bounds.
77      */
78     static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = NULL);
79 
80     /**
81      *  Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
82      *  which can mean that the format of the encoded data was not recognized/supported.
83      *
84      *  If a subset is specified, it must be contained within the encoded data's bounds.
85      *
86      *  Regardless of success or failure, the caller is responsible for managing their ownership
87      *  of the data.
88      */
89     static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = NULL);
90 
91     /**
92      *  Create a new image from the specified descriptor. Note - the caller is responsible for
93      *  managing the lifetime of the underlying platform texture.
94      *
95      *  Will return NULL if the specified descriptor is unsupported.
96      */
NewFromTexture(GrContext * ctx,const GrBackendTextureDesc & desc)97     static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
98         return NewFromTexture(ctx, desc, kPremul_SkAlphaType, NULL, NULL);
99     }
100 
NewFromTexture(GrContext * ctx,const GrBackendTextureDesc & de,SkAlphaType at)101     static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& de, SkAlphaType at) {
102         return NewFromTexture(ctx, de, at, NULL, NULL);
103     }
104 
105     typedef void (*TextureReleaseProc)(ReleaseContext);
106 
107     /**
108      *  Create a new image from the specified descriptor. The underlying platform texture must stay
109      *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
110      *  no longer is holding a reference to it.
111      *
112      *  Will return NULL if the specified descriptor is unsupported.
113      */
114     static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
115                                    TextureReleaseProc, ReleaseContext);
116 
117     /**
118      *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
119      *  texture when the image is released.
120      *
121      *  Will return NULL if the specified descriptor is unsupported.
122      */
123     static SkImage* NewFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
124                                           SkAlphaType = kPremul_SkAlphaType);
125 
126     /**
127      *  Create a new image by copying the pixels from the specified descriptor. No reference is
128      *  kept to the original platform texture.
129      *
130      *  Will return NULL if the specified descriptor is unsupported.
131      */
132     static SkImage* NewFromTextureCopy(GrContext*, const GrBackendTextureDesc&,
133                                        SkAlphaType = kPremul_SkAlphaType);
134 
135     /**
136      *  Create a new image by copying the pixels from the specified y, u, v textures. The data
137      *  from the textures is immediately ingested into the image and the textures can be modified or
138      *  deleted after the function returns. The image will have the dimensions of the y texture.
139      */
140     static SkImage* NewFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
141                                            const GrBackendObject yuvTextureHandles[3],
142                                            const SkISize yuvSizes[3],
143                                            GrSurfaceOrigin);
144 
145     static SkImage* NewFromPicture(const SkPicture*, const SkISize& dimensions,
146                                    const SkMatrix*, const SkPaint*);
147 
148     ///////////////////////////////////////////////////////////////////////////////////////////////
149 
width()150     int width() const { return fWidth; }
height()151     int height() const { return fHeight; }
dimensions()152     SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
bounds()153     SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
uniqueID()154     uint32_t uniqueID() const { return fUniqueID; }
isOpaque()155     virtual bool isOpaque() const { return false; }
156 
157     /**
158      * Extracts YUV planes from the SkImage and stores them in client-provided memory. The sizes
159      * planes and rowBytes arrays are ordered [y, u, v].
160      */
161     bool readYUV8Planes(const SkISize[3], void* const planes[3], const size_t rowBytes[3],
162                         SkYUVColorSpace) const;
163 
164     virtual SkShader* newShader(SkShader::TileMode,
165                                 SkShader::TileMode,
166                                 const SkMatrix* localMatrix = NULL) const;
167 
168     /**
169      *  If the image has direct access to its pixels (i.e. they are in local
170      *  RAM) return the (const) address of those pixels, and if not null, return
171      *  the ImageInfo and rowBytes. The returned address is only valid while
172      *  the image object is in scope.
173      *
174      *  On failure, returns NULL and the info and rowBytes parameters are
175      *  ignored.
176      */
177     const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const;
178 
179     /**
180      *  If the image has direct access to its pixels (i.e. they are in local
181      *  RAM) return the (const) address of those pixels, and if not null, return
182      *  true, and if pixmap is not NULL, set it to point into the image.
183      *
184      *  On failure, return false and ignore the pixmap parameter.
185      */
186     bool peekPixels(SkPixmap* pixmap) const;
187 
188     /**
189      *  Some images have to perform preliminary work in preparation for drawing. This can be
190      *  decoding, uploading to a GPU, or other tasks. These happen automatically when an image
191      *  is drawn, and often they are cached so that the cost is only paid the first time.
192      *
193      *  Preroll() can be called before drawing to try to perform this prepatory work ahead of time.
194      *  For images that have no such work, this returns instantly. Others may do some thing to
195      *  prepare their cache and then return.
196      *
197      *  If the image will drawn to a GPU-backed canvas or surface, pass the associated GrContext.
198      *  If the image will be drawn to any other type of canvas or surface, pass null.
199      */
200     void preroll(GrContext* = nullptr) const;
201 
202     // DEPRECATED
203     GrTexture* getTexture() const;
204 
205     /**
206      *  Returns true if the image is texture backed.
207      */
208     bool isTextureBacked() const;
209 
210     /**
211      *  Retrieves the backend API handle of the texture. If flushPendingGrContextIO then the
212      *  GrContext will issue to the backend API any deferred IO operations on the texture before
213      *  returning.
214      */
215     GrBackendObject getTextureHandle(bool flushPendingGrContextIO) const;
216 
217     /**
218      *  Hints to image calls where the system might cache computed intermediates (e.g. the results
219      *  of decoding or a read-back from the GPU. Passing kAllow signals that the system's default
220      *  behavior is fine. Passing kDisallow signals that caching should be avoided.
221      */
222      enum CachingHint {
223         kAllow_CachingHint,
224         kDisallow_CachingHint,
225     };
226 
227     /**
228      *  Copy the pixels from the image into the specified buffer (pixels + rowBytes),
229      *  converting them into the requested format (dstInfo). The image pixels are read
230      *  starting at the specified (srcX,srcY) location.
231      *
232      *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
233      *
234      *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
235      *
236      *  srcR is intersected with the bounds of the image. If this intersection is not empty,
237      *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
238      *  corresponding src pixels, performing any colortype/alphatype transformations needed
239      *  (in the case where the src and dst have different colortypes or alphatypes).
240      *
241      *  This call can fail, returning false, for several reasons:
242      *  - If srcR does not intersect the image bounds.
243      *  - If the requested colortype/alphatype cannot be converted from the image's types.
244      */
245     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
246                     int srcX, int srcY, CachingHint = kAllow_CachingHint) const;
247 
248     bool readPixels(const SkPixmap& dst, int srcX, int srcY,
249                     CachingHint = kAllow_CachingHint) const;
250 
251     /**
252      *  Copy the pixels from this image into the dst pixmap, converting as needed into dst's
253      *  colortype/alphatype. If the conversion cannot be performed, false is returned.
254      *
255      *  If dst's dimensions differ from the src dimension, the image will be scaled, applying the
256      *  specified filter-quality.
257      */
258     bool scalePixels(const SkPixmap& dst, SkFilterQuality, CachingHint = kAllow_CachingHint) const;
259 
260     /**
261      *  Encode the image's pixels and return the result as a new SkData, which
262      *  the caller must manage (i.e. call unref() when they are done).
263      *
264      *  If the image type cannot be encoded, or the requested encoder type is
265      *  not supported, this will return NULL.
266      *
267      *  Note: this will attempt to encode the image's pixels in the specified format,
268      *  even if the image returns a data from refEncoded(). That data will be ignored.
269      */
270     SkData* encode(SkImageEncoder::Type, int quality) const;
271 
272     /**
273      *  Encode the image and return the result as a caller-managed SkData.  This will
274      *  attempt to reuse existing encoded data (as returned by refEncoded).
275      *
276      *  We defer to the SkPixelSerializer both for vetting existing encoded data
277      *  (useEncodedData) and for encoding the image (encode) when no such data is
278      *  present or is rejected by the serializer.
279      *
280      *  If not specified, we use a default serializer which 1) always accepts existing data
281      *  (in any format) and 2) encodes to PNG.
282      *
283      *  If no compatible encoded data exists and encoding fails, this method will also
284      *  fail (return NULL).
285      */
286     SkData* encode(SkPixelSerializer* = nullptr) const;
287 
288     /**
289      *  If the image already has its contents in encoded form (e.g. PNG or JPEG), return a ref
290      *  to that data (which the caller must call unref() on). The caller is responsible for calling
291      *  unref on the data when they are done.
292      *
293      *  If the image does not already has its contents in encoded form, return NULL.
294      *
295      *  Note: to force the image to return its contents as encoded data, try calling encode(...).
296      */
297     SkData* refEncoded() const;
298 
299     const char* toString(SkString*) const;
300 
301     /**
302      *  Return a new image that is a subset of this image. The underlying implementation may
303      *  share the pixels, or it may make a copy.
304      *
305      *  If subset does not intersect the bounds of this image, or the copy/share cannot be made,
306      *  NULL will be returned.
307      */
308     SkImage* newSubset(const SkIRect& subset) const;
309 
310     /**
311      *  Ensures that an image is backed by a texture (when GrContext is non-null). If no
312      *  transformation is required, the returned image may be the same as this image. If the this
313      *  image is from a different GrContext, this will fail.
314      */
315     SkImage* newTextureImage(GrContext*) const;
316 
317     // Helper functions to convert to SkBitmap
318 
319     enum LegacyBitmapMode {
320         kRO_LegacyBitmapMode,
321         kRW_LegacyBitmapMode,
322     };
323 
324     /**
325      *  Attempt to create a bitmap with the same pixels as the image. The result will always be
326      *  a raster-backed bitmap (texture-backed bitmaps are DEPRECATED, and not supported here).
327      *
328      *  If the mode is kRO (read-only), the resulting bitmap will be marked as immutable.
329      *
330      *  On succcess, returns true. On failure, returns false and the bitmap parameter will be reset
331      *  to empty.
332      */
333     bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
334 
335     /**
336      *  Returns true if the image is backed by an image-generator or other src that creates
337      *  (and caches) its pixels / texture on-demand.
338      */
339     bool isLazyGenerated() const;
340 
341 protected:
342     SkImage(int width, int height, uint32_t uniqueID);
343 
344 private:
345     const int       fWidth;
346     const int       fHeight;
347     const uint32_t  fUniqueID;
348 
349     typedef SkRefCnt INHERITED;
350 };
351 
352 #endif
353