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