blob: 99562f4445a95148378e77154fea4845e82c2481 [file] [log] [blame]
reed@google.combba65d92012-07-25 14:42:15 +00001/*
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
reedf803da12015-01-23 05:58:07 -080011#include "SkFilterQuality.h"
reed@google.com3443fd82013-11-13 19:09:13 +000012#include "SkImageInfo.h"
scroggo@google.com7def5e12013-05-31 14:00:10 +000013#include "SkImageEncoder.h"
reed@google.comf6627b72012-07-27 18:02:50 +000014#include "SkRefCnt.h"
15#include "SkScalar.h"
piotaixrcef04f82014-07-14 07:48:04 -070016#include "SkShader.h"
reed@google.comf6627b72012-07-27 18:02:50 +000017
18class SkData;
19class SkCanvas;
reed759373a2015-07-03 21:01:10 -070020class SkColorTable;
halcanaryea4673f2014-08-18 08:27:09 -070021class SkImageGenerator;
reed@google.comf6627b72012-07-27 18:02:50 +000022class SkPaint;
reedd5b75632015-08-13 09:37:45 -070023class SkPicture;
fmalita2be71252015-09-03 07:17:25 -070024class SkPixelSerializer;
reed41af9662015-01-05 07:49:08 -080025class SkString;
reed4af267b2014-11-21 08:46:37 -080026class SkSurface;
27class SkSurfaceProps;
reed@google.com5d4ba882012-07-31 15:45:27 +000028class GrContext;
robertphillips@google.com72ba6682012-10-31 14:58:16 +000029class GrTexture;
reed@google.comf6627b72012-07-27 18:02:50 +000030
reed@google.combba65d92012-07-25 14:42:15 +000031/**
32 * SkImage is an abstraction for drawing a rectagle of pixels, though the
33 * particular type of image could be actually storing its data on the GPU, or
34 * as drawing commands (picture or PDF or otherwise), ready to be played back
35 * into another canvas.
36 *
37 * The content of SkImage is always immutable, though the actual storage may
38 * change, if for example that image can be re-created via encoded data or
39 * other means.
reedb2497c22014-12-31 12:31:43 -080040 *
41 * SkImage always has a non-zero dimensions. If there is a request to create a new image, either
42 * directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be
43 * returned.
reed@google.combba65d92012-07-25 14:42:15 +000044 */
junov@chromium.org96447be2013-04-18 13:28:19 +000045class SK_API SkImage : public SkRefCnt {
reed@google.combba65d92012-07-25 14:42:15 +000046public:
reed@google.com2bd8b812013-11-01 13:46:54 +000047 typedef SkImageInfo Info;
reedde499882015-06-18 13:41:40 -070048 typedef void* ReleaseContext;
reed@google.combba65d92012-07-25 14:42:15 +000049
reed759373a2015-07-03 21:01:10 -070050 static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes,
51 SkColorTable* ctable = NULL);
mike@reedtribe.orgb9476252012-11-15 02:37:45 +000052 static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
commit-bot@chromium.org4d24b742013-07-25 23:29:40 +000053
reedde499882015-06-18 13:41:40 -070054 typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext);
55
56 /**
57 * Return a new Image referencing the specified pixels. These must remain valid and unchanged
58 * until the specified release-proc is called, indicating that Skia no longer has a reference
59 * to the pixels.
60 *
61 * Returns NULL if the requested Info is unsupported.
62 */
63 static SkImage* NewFromRaster(const Info&, const void* pixels, size_t rowBytes,
64 RasterReleaseProc, ReleaseContext);
65
commit-bot@chromium.org4d24b742013-07-25 23:29:40 +000066 /**
reed56179002015-07-07 06:11:19 -070067 * Construct a new image from the specified bitmap. If the bitmap is marked immutable, and
68 * its pixel memory is shareable, it may be shared instead of copied.
69 */
70 static SkImage* NewFromBitmap(const SkBitmap&);
71
72 /**
halcanaryea4673f2014-08-18 08:27:09 -070073 * Construct a new SkImage based on the given ImageGenerator.
74 * This function will always take ownership of the passed
75 * ImageGenerator. Returns NULL on error.
reed871872f2015-06-22 12:48:26 -070076 *
77 * If a subset is specified, it must be contained within the generator's bounds.
halcanaryea4673f2014-08-18 08:27:09 -070078 */
reed871872f2015-06-22 12:48:26 -070079 static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = NULL);
halcanaryea4673f2014-08-18 08:27:09 -070080
reed5965c8a2015-01-07 18:04:45 -080081 /**
82 * Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
83 * which can mean that the format of the encoded data was not recognized/supported.
84 *
reed871872f2015-06-22 12:48:26 -070085 * If a subset is specified, it must be contained within the encoded data's bounds.
86 *
reed5965c8a2015-01-07 18:04:45 -080087 * Regardless of success or failure, the caller is responsible for managing their ownership
88 * of the data.
89 */
reed871872f2015-06-22 12:48:26 -070090 static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = NULL);
91
reed8b26b992015-05-07 15:36:17 -070092 /**
93 * Create a new image from the specified descriptor. Note - the caller is responsible for
94 * managing the lifetime of the underlying platform texture.
95 *
96 * Will return NULL if the specified descriptor is unsupported.
97 */
reedde499882015-06-18 13:41:40 -070098 static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
99 return NewFromTexture(ctx, desc, kPremul_SkAlphaType, NULL, NULL);
100 }
101
102 static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& de, SkAlphaType at) {
103 return NewFromTexture(ctx, de, at, NULL, NULL);
104 }
105
106 typedef void (*TextureReleaseProc)(ReleaseContext);
107
108 /**
109 * Create a new image from the specified descriptor. The underlying platform texture must stay
110 * valid and unaltered until the specified release-proc is invoked, indicating that Skia
bsalomona4497792015-07-23 12:22:19 -0700111 * no longer is holding a reference to it.
reedde499882015-06-18 13:41:40 -0700112 *
113 * Will return NULL if the specified descriptor is unsupported.
114 */
115 static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
116 TextureReleaseProc, ReleaseContext);
reed8b26b992015-05-07 15:36:17 -0700117
118 /**
bsalomon6dc6f5f2015-06-18 09:12:16 -0700119 * Create a new image from the specified descriptor. Note - Skia will delete or recycle the
120 * texture when the image is released.
121 *
122 * Will return NULL if the specified descriptor is unsupported.
123 */
124 static SkImage* NewFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
125 SkAlphaType = kPremul_SkAlphaType);
126
127 /**
reed8b26b992015-05-07 15:36:17 -0700128 * Create a new image by copying the pixels from the specified descriptor. No reference is
129 * kept to the original platform texture.
130 *
131 * Will return NULL if the specified descriptor is unsupported.
132 */
133 static SkImage* NewFromTextureCopy(GrContext*, const GrBackendTextureDesc&,
134 SkAlphaType = kPremul_SkAlphaType);
135
bsalomon993a4212015-05-29 11:37:25 -0700136 /**
137 * Create a new image by copying the pixels from the specified y, u, v textures. The data
138 * from the textures is immediately ingested into the image and the textures can be modified or
139 * deleted after the function returns. The image will have the dimensions of the y texture.
140 */
141 static SkImage* NewFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
142 const GrBackendObject yuvTextureHandles[3],
143 const SkISize yuvSizes[3],
144 GrSurfaceOrigin);
145
reedd5b75632015-08-13 09:37:45 -0700146 static SkImage* NewFromPicture(const SkPicture*, const SkISize& dimensions,
147 const SkMatrix*, const SkPaint*);
148
149 ///////////////////////////////////////////////////////////////////////////////////////////////
150
reed@google.comf6627b72012-07-27 18:02:50 +0000151 int width() const { return fWidth; }
152 int height() const { return fHeight; }
reed85d91782015-09-10 14:33:38 -0700153 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
154 SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
reed@google.comf6627b72012-07-27 18:02:50 +0000155 uint32_t uniqueID() const { return fUniqueID; }
reed4ef0c8a2015-01-13 04:00:55 -0800156 virtual bool isOpaque() const { return false; }
reed@google.comf6627b72012-07-27 18:02:50 +0000157
piotaixr76d5b472014-07-22 15:02:05 -0700158 virtual SkShader* newShader(SkShader::TileMode,
159 SkShader::TileMode,
160 const SkMatrix* localMatrix = NULL) const;
reed@google.comf6627b72012-07-27 18:02:50 +0000161
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000162 /**
reed@google.com4f7c6152014-02-06 14:11:56 +0000163 * If the image has direct access to its pixels (i.e. they are in local
164 * RAM) return the (const) address of those pixels, and if not null, return
165 * the ImageInfo and rowBytes. The returned address is only valid while
166 * the image object is in scope.
167 *
168 * On failure, returns NULL and the info and rowBytes parameters are
169 * ignored.
170 */
171 const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const;
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000172
reed871872f2015-06-22 12:48:26 -0700173 /**
174 * If the image has direct access to its pixels (i.e. they are in local
175 * RAM) return the (const) address of those pixels, and if not null, return
176 * true, and if pixmap is not NULL, set it to point into the image.
177 *
178 * On failure, return false and ignore the pixmap parameter.
179 */
180 bool peekPixels(SkPixmap* pixmap) const;
181
reed86e90fa2015-09-01 12:22:32 -0700182 /**
183 * Some images have to perform preliminary work in preparation for drawing. This can be
184 * decoding, uploading to a GPU, or other tasks. These happen automatically when an image
185 * is drawn, and often they are cached so that the cost is only paid the first time.
186 *
187 * Preroll() can be called before drawing to try to perform this prepatory work ahead of time.
188 * For images that have no such work, this returns instantly. Others may do some thing to
189 * prepare their cache and then return.
190 *
191 * If the image will drawn to a GPU-backed canvas or surface, pass the associated GrContext.
192 * If the image will be drawn to any other type of canvas or surface, pass null.
193 */
194 void preroll(GrContext* = nullptr) const;
195
bsalomon55812362015-06-10 08:49:28 -0700196 // DEPRECATED
197 GrTexture* getTexture() const;
198
199 /**
200 * Returns true if the image is texture backed.
201 */
202 bool isTextureBacked() const;
203
mtklein2766c002015-06-26 11:45:03 -0700204 /**
bsalomonc49e8682015-06-30 11:37:35 -0700205 * Retrieves the backend API handle of the texture. If flushPendingGrContextIO then the
206 * GrContext will issue to the backend API any deferred IO operations on the texture before
bsalomon55812362015-06-10 08:49:28 -0700207 * returning.
208 */
bsalomonc49e8682015-06-30 11:37:35 -0700209 GrBackendObject getTextureHandle(bool flushPendingGrContextIO) const;
bsalomon55812362015-06-10 08:49:28 -0700210
reed@google.com4f7c6152014-02-06 14:11:56 +0000211 /**
reed96472de2014-12-10 09:53:42 -0800212 * Copy the pixels from the image into the specified buffer (pixels + rowBytes),
213 * converting them into the requested format (dstInfo). The image pixels are read
214 * starting at the specified (srcX,srcY) location.
215 *
216 * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
217 *
218 * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
219 *
220 * srcR is intersected with the bounds of the image. If this intersection is not empty,
221 * then we have two sets of pixels (of equal size). Replace the dst pixels with the
222 * corresponding src pixels, performing any colortype/alphatype transformations needed
223 * (in the case where the src and dst have different colortypes or alphatypes).
224 *
225 * This call can fail, returning false, for several reasons:
226 * - If srcR does not intersect the image bounds.
227 * - If the requested colortype/alphatype cannot be converted from the image's types.
228 */
229 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
230 int srcX, int srcY) const;
231
reed871872f2015-06-22 12:48:26 -0700232 bool readPixels(const SkPixmap& dst, int srcX, int srcY) const;
233
reed96472de2014-12-10 09:53:42 -0800234 /**
reed@google.com4b0757b2013-05-20 16:33:41 +0000235 * Encode the image's pixels and return the result as a new SkData, which
236 * the caller must manage (i.e. call unref() when they are done).
237 *
238 * If the image type cannot be encoded, or the requested encoder type is
239 * not supported, this will return NULL.
fmalita2be71252015-09-03 07:17:25 -0700240 *
241 * Note: this will attempt to encode the image's pixels in the specified format,
242 * even if the image returns a data from refEncoded(). That data will be ignored.
reed@google.com4b0757b2013-05-20 16:33:41 +0000243 */
reed871872f2015-06-22 12:48:26 -0700244 SkData* encode(SkImageEncoder::Type, int quality) const;
245
fmalita2be71252015-09-03 07:17:25 -0700246 /**
247 * Encode the image and return the result as a caller-managed SkData. This will
248 * attempt to reuse existing encoded data (as returned by refEncoded).
249 *
250 * We defer to the SkPixelSerializer both for vetting existing encoded data
251 * (useEncodedData) and for encoding the image (encodePixels) when no such data is
252 * present or is rejected by the serializer.
253 *
254 * If not specified, we use a default serializer which 1) always accepts existing data
255 * (in any format) and 2) encodes to PNG.
256 *
257 * If no compatible encoded data exists and encoding fails, this method will also
258 * fail (return NULL).
259 */
260 SkData* encode(SkPixelSerializer* = nullptr) const;
reed871872f2015-06-22 12:48:26 -0700261
262 /**
263 * If the image already has its contents in encoded form (e.g. PNG or JPEG), return a ref
264 * to that data (which the caller must call unref() on). The caller is responsible for calling
265 * unref on the data when they are done.
266 *
267 * If the image does not already has its contents in encoded form, return NULL.
268 *
269 * Note: to force the image to return its contents as encoded data, try calling encode(...).
270 */
271 SkData* refEncoded() const;
reed@google.com4b0757b2013-05-20 16:33:41 +0000272
reedf8d18742015-01-02 20:45:37 -0800273 const char* toString(SkString*) const;
274
reed7b6945b2015-09-24 00:50:58 -0700275#ifdef SK_SUPPORT_LEGACY_NEWIMAGE
reedf803da12015-01-23 05:58:07 -0800276 /**
277 * Return an image that is a rescale of this image (using newWidth, newHeight).
278 *
279 * If subset is NULL, then the entire original image is used as the src for the scaling.
280 * If subset is not NULL, then it specifies subset of src-pixels used for scaling. If
281 * subset extends beyond the bounds of the original image, then NULL is returned.
282 *
283 * Notes:
284 * - newWidth and newHeight must be > 0 or NULL will be returned.
285 *
286 * - it is legal for the returned image to be the same instance as the src image
287 * (if the new dimensions == the src dimensions and subset is NULL or == src dimensions).
288 *
289 * - it is legal for the "scaled" image to have changed its SkAlphaType from unpremul
290 * to premul (as required by the impl). The image should draw (nearly) identically,
291 * since during drawing we will "apply the alpha" to the pixels. Future optimizations
292 * may take away this caveat, preserving unpremul.
293 */
reed7b6945b2015-09-24 00:50:58 -0700294 SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset) const;
295#endif
296
297 /**
298 * Return a new image that is a subset of this image. The underlying implementation may
299 * share the pixels, or it may make a copy.
300 *
301 * If subset does not intersect the bounds of this image, or the copy/share cannot be made,
302 * NULL will be returned.
303 */
304 SkImage* newSubset(const SkIRect& subset) const;
reedf803da12015-01-23 05:58:07 -0800305
reed3c065112015-07-08 12:46:22 -0700306 // Helper functions to convert to SkBitmap
307
308 enum LegacyBitmapMode {
309 kRO_LegacyBitmapMode,
310 kRW_LegacyBitmapMode,
311 };
312
313 /**
314 * Attempt to create a bitmap with the same pixels as the image. The result will always be
315 * a raster-backed bitmap (texture-backed bitmaps are DEPRECATED, and not supported here).
316 *
317 * If the mode is kRO (read-only), the resulting bitmap will be marked as immutable.
318 *
319 * On succcess, returns true. On failure, returns false and the bitmap parameter will be reset
320 * to empty.
321 */
322 bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
323
fmalitaddbbdda2015-08-20 08:47:26 -0700324 /**
325 * Returns true if the image is backed by an image-generator or other src that creates
326 * (and caches) its pixels / texture on-demand.
327 */
328 bool isLazyGenerated() const;
329
reed@google.comf6627b72012-07-27 18:02:50 +0000330protected:
reed80c772b2015-07-30 18:58:23 -0700331 SkImage(int width, int height, uint32_t uniqueID);
reed@google.comf6627b72012-07-27 18:02:50 +0000332
333private:
334 const int fWidth;
335 const int fHeight;
336 const uint32_t fUniqueID;
337
reed@google.com7edfb492012-08-28 12:48:35 +0000338 typedef SkRefCnt INHERITED;
reed@google.combba65d92012-07-25 14:42:15 +0000339};
340
reed@google.combba65d92012-07-25 14:42:15 +0000341#endif