xref: /aosp_15_r20/external/skia/include/core/SkImage.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "include/core/SkAlphaType.h"
12 #include "include/core/SkImageInfo.h"
13 #include "include/core/SkRect.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkSize.h"
16 #include "include/private/base/SkAPI.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <memory>
21 #include <optional>
22 
23 class GrDirectContext;
24 class GrRecordingContext;
25 class SkBitmap;
26 class SkColorSpace;
27 class SkData;
28 class SkImage;
29 class SkImageFilter;
30 class SkImageGenerator;
31 class SkMatrix;
32 class SkMipmap;
33 class SkPaint;
34 class SkPicture;
35 class SkPixmap;
36 class SkShader;
37 class SkSurfaceProps;
38 enum SkColorType : int;
39 enum class SkTextureCompressionType;
40 enum class SkTileMode;
41 
42 struct SkIPoint;
43 struct SkSamplingOptions;
44 
45 namespace skgpu::graphite { class Recorder; }
46 
47 namespace SkImages {
48 
49 /** Caller data passed to RasterReleaseProc; may be nullptr. */
50 using ReleaseContext = void*;
51 /** Function called when SkImage no longer shares pixels. ReleaseContext is
52     provided by caller when SkImage is created, and may be nullptr.
53 */
54 using RasterReleaseProc = void(const void* pixels, ReleaseContext);
55 
56 /** Creates a CPU-backed SkImage from bitmap, sharing or copying bitmap pixels. If the bitmap
57     is marked immutable, and its pixel memory is shareable, it may be shared
58     instead of copied.
59 
60     SkImage is returned if bitmap is valid. Valid SkBitmap parameters include:
61     dimensions are greater than zero;
62     each dimension fits in 29 bits;
63     SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
64     row bytes are large enough to hold one row of pixels;
65     pixel address is not nullptr.
66 
67     @param bitmap  SkImageInfo, row bytes, and pixels
68     @return        created SkImage, or nullptr
69 */
70 SK_API sk_sp<SkImage> RasterFromBitmap(const SkBitmap& bitmap);
71 
72 /** Creates a CPU-backed SkImage from compressed data.
73 
74     This method will decompress the compressed data and create an image wrapping
75     it. Any mipmap levels present in the compressed data are discarded.
76 
77     @param data     compressed data to store in SkImage
78     @param width    width of full SkImage
79     @param height   height of full SkImage
80     @param type     type of compression used
81     @return         created SkImage, or nullptr
82 */
83 SK_API sk_sp<SkImage> RasterFromCompressedTextureData(sk_sp<SkData> data,
84                                                       int width,
85                                                       int height,
86                                                       SkTextureCompressionType type);
87 
88 /**
89  *  Return a SkImage using the encoded data, but attempts to defer decoding until the
90  *  image is actually used/drawn. This deferral allows the system to cache the result, either on the
91  *  CPU or on the GPU, depending on where the image is drawn. If memory is low, the cache may
92  *  be purged, causing the next draw of the image to have to re-decode.
93  *
94  *  If alphaType is nullopt, the image's alpha type will be chosen automatically based on the
95  *  image format. Transparent images will default to kPremul_SkAlphaType. If alphaType contains
96  *  kPremul_SkAlphaType or kUnpremul_SkAlphaType, that alpha type will be used. Forcing opaque
97  *  (passing kOpaque_SkAlphaType) is not allowed, and will return nullptr.
98  *
99  *  If the encoded format is not supported, nullptr is returned.
100  *
101  *  If possible, clients should use SkCodecs::DeferredImage instead.
102  *
103  *  @param encoded  the encoded data
104  *  @return         created SkImage, or nullptr
105 
106     example: https://fiddle.skia.org/c/@Image_DeferredFromEncodedData
107 */
108 SK_API sk_sp<SkImage> DeferredFromEncodedData(sk_sp<SkData> encoded,
109                                               std::optional<SkAlphaType> alphaType = std::nullopt);
110 
111 /** Creates SkImage from data returned by imageGenerator. The image data will not be created
112     (on either the CPU or GPU) until the image is actually drawn.
113     Generated data is owned by SkImage and may not be shared or accessed.
114 
115     SkImage is returned if generator data is valid. Valid data parameters vary by type of data
116     and platform.
117 
118     imageGenerator may wrap SkPicture data, codec data, or custom data.
119 
120     @param imageGenerator  stock or custom routines to retrieve SkImage
121     @return                created SkImage, or nullptr
122 */
123 SK_API sk_sp<SkImage> DeferredFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator);
124 
125 enum class BitDepth {
126     kU8,   //!< uses 8-bit unsigned int per color component
127     kF16,  //!< uses 16-bit float per color component
128 };
129 
130 /** Creates SkImage from picture. Returned SkImage width and height are set by dimensions.
131     SkImage draws picture with matrix and paint, set to bitDepth and colorSpace.
132 
133     The Picture data is not turned into an image (CPU or GPU) until it is drawn.
134 
135     If matrix is nullptr, draws with identity SkMatrix. If paint is nullptr, draws
136     with default SkPaint. colorSpace may be nullptr.
137 
138     @param picture     stream of drawing commands
139     @param dimensions  width and height
140     @param matrix      SkMatrix to rotate, scale, translate, and so on; may be nullptr
141     @param paint       SkPaint to apply transparency, filtering, and so on; may be nullptr
142     @param bitDepth    8-bit integer or 16-bit float: per component
143     @param colorSpace  range of colors; may be nullptr
144     @param props       props to use when rasterizing the picture
145     @return            created SkImage, or nullptr
146 */
147 SK_API sk_sp<SkImage> DeferredFromPicture(sk_sp<SkPicture> picture,
148                                           const SkISize& dimensions,
149                                           const SkMatrix* matrix,
150                                           const SkPaint* paint,
151                                           BitDepth bitDepth,
152                                           sk_sp<SkColorSpace> colorSpace,
153                                           SkSurfaceProps props);
154 SK_API sk_sp<SkImage> DeferredFromPicture(sk_sp<SkPicture> picture,
155                                           const SkISize& dimensions,
156                                           const SkMatrix* matrix,
157                                           const SkPaint* paint,
158                                           BitDepth bitDepth,
159                                           sk_sp<SkColorSpace> colorSpace);
160 
161 /** Creates a CPU-backed SkImage from pixmap, copying the pixel data.
162     As a result, pixmap pixels may be modified or deleted without affecting SkImage.
163 
164     SkImage is returned if SkPixmap is valid. Valid SkPixmap parameters include:
165     dimensions are greater than zero;
166     each dimension fits in 29 bits;
167     SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
168     row bytes are large enough to hold one row of pixels;
169     pixel address is not nullptr.
170 
171     @param pixmap  SkImageInfo, pixel address, and row bytes
172     @return        copy of SkPixmap pixels, or nullptr
173 
174     example: https://fiddle.skia.org/c/@Image_RasterFromPixmapCopy
175 */
176 SK_API sk_sp<SkImage> RasterFromPixmapCopy(const SkPixmap& pixmap);
177 
178 /** Creates CPU-backed SkImage from pixmap, sharing SkPixmap pixels. Pixels must remain valid and
179     unchanged until rasterReleaseProc is called. rasterReleaseProc is passed
180     releaseContext when SkImage is deleted or no longer refers to pixmap pixels.
181 
182     Pass nullptr for rasterReleaseProc to share SkPixmap without requiring a callback
183     when SkImage is released. Pass nullptr for releaseContext if rasterReleaseProc
184     does not require state.
185 
186     SkImage is returned if pixmap is valid. Valid SkPixmap parameters include:
187     dimensions are greater than zero;
188     each dimension fits in 29 bits;
189     SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
190     row bytes are large enough to hold one row of pixels;
191     pixel address is not nullptr.
192 
193     @param pixmap             SkImageInfo, pixel address, and row bytes
194     @param rasterReleaseProc  function called when pixels can be released; or nullptr
195     @param releaseContext     state passed to rasterReleaseProc; or nullptr
196     @return                   SkImage sharing pixmap
197 */
198 SK_API sk_sp<SkImage> RasterFromPixmap(const SkPixmap& pixmap,
199                                        RasterReleaseProc rasterReleaseProc,
200                                        ReleaseContext releaseContext);
201 
202 /** Creates CPU-backed SkImage from pixel data described by info.
203     The pixels data will *not* be copied.
204 
205     SkImage is returned if SkImageInfo is valid. Valid SkImageInfo parameters include:
206     dimensions are greater than zero;
207     each dimension fits in 29 bits;
208     SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
209     rowBytes are large enough to hold one row of pixels;
210     pixels is not nullptr, and contains enough data for SkImage.
211 
212     @param info      contains width, height, SkAlphaType, SkColorType, SkColorSpace
213     @param pixels    address or pixel storage
214     @param rowBytes  size of pixel row or larger
215     @return          SkImage sharing pixels, or nullptr
216 */
217 SK_API sk_sp<SkImage> RasterFromData(const SkImageInfo& info,
218                                      sk_sp<SkData> pixels,
219                                      size_t rowBytes);
220 
221 /** Creates a filtered SkImage on the CPU. filter processes the src image, potentially changing
222     the color, position, and size. subset is the bounds of src that are processed
223     by filter. clipBounds is the expected bounds of the filtered SkImage. outSubset
224     is required storage for the actual bounds of the filtered SkImage. offset is
225     required storage for translation of returned SkImage.
226 
227     Returns nullptr a filtered result could not be created. If nullptr is returned, outSubset
228     and offset are undefined.
229 
230     Useful for animation of SkImageFilter that varies size from frame to frame.
231     outSubset describes the valid bounds of returned image. offset translates the returned SkImage
232     to keep subsequent animation frames aligned with respect to each other.
233 
234     @param src         the image to be filtered
235     @param filter      the image filter to be applied
236     @param subset      bounds of SkImage processed by filter
237     @param clipBounds  expected bounds of filtered SkImage
238     @param outSubset   storage for returned SkImage bounds
239     @param offset      storage for returned SkImage translation
240     @return            filtered SkImage, or nullptr
241 */
242 SK_API sk_sp<SkImage> MakeWithFilter(sk_sp<SkImage> src,
243                                      const SkImageFilter* filter,
244                                      const SkIRect& subset,
245                                      const SkIRect& clipBounds,
246                                      SkIRect* outSubset,
247                                      SkIPoint* offset);
248 
249 }  // namespace SkImages
250 
251 /** \class SkImage
252     SkImage describes a two dimensional array of pixels to draw. The pixels may be
253     decoded in a raster bitmap, encoded in a SkPicture or compressed data stream,
254     or located in GPU memory as a GPU texture.
255 
256     SkImage cannot be modified after it is created. SkImage may allocate additional
257     storage as needed; for instance, an encoded SkImage may decode when drawn.
258 
259     SkImage width and height are greater than zero. Creating an SkImage with zero width
260     or height returns SkImage equal to nullptr.
261 
262     SkImage may be created from SkBitmap, SkPixmap, SkSurface, SkPicture, encoded streams,
263     GPU texture, YUV_ColorSpace data, or hardware buffer. Encoded streams supported
264     include BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP. Supported encoding details
265     vary with platform.
266 
267     See SkImages namespace for the static factory methods to make SkImages.
268 
269     Clients should *not* subclass SkImage as there is a lot of internal machinery that is
270     not publicly accessible.
271 */
272 class SK_API SkImage : public SkRefCnt {
273 public:
274     /** Returns a SkImageInfo describing the width, height, color type, alpha type, and color space
275         of the SkImage.
276 
277         @return  image info of SkImage.
278     */
imageInfo()279     const SkImageInfo& imageInfo() const { return fInfo; }
280 
281     /** Returns pixel count in each row.
282 
283         @return  pixel width in SkImage
284     */
width()285     int width() const { return fInfo.width(); }
286 
287     /** Returns pixel row count.
288 
289         @return  pixel height in SkImage
290     */
height()291     int height() const { return fInfo.height(); }
292 
293     /** Returns SkISize { width(), height() }.
294 
295         @return  integral size of width() and height()
296     */
dimensions()297     SkISize dimensions() const { return SkISize::Make(fInfo.width(), fInfo.height()); }
298 
299     /** Returns SkIRect { 0, 0, width(), height() }.
300 
301         @return  integral rectangle from origin to width() and height()
302     */
bounds()303     SkIRect bounds() const { return SkIRect::MakeWH(fInfo.width(), fInfo.height()); }
304 
305     /** Returns value unique to image. SkImage contents cannot change after SkImage is
306         created. Any operation to create a new SkImage will receive generate a new
307         unique number.
308 
309         @return  unique identifier
310     */
uniqueID()311     uint32_t uniqueID() const { return fUniqueID; }
312 
313     /** Returns SkAlphaType.
314 
315         SkAlphaType returned was a parameter to an SkImage constructor,
316         or was parsed from encoded data.
317 
318         @return  SkAlphaType in SkImage
319 
320         example: https://fiddle.skia.org/c/@Image_alphaType
321     */
322     SkAlphaType alphaType() const;
323 
324     /** Returns SkColorType if known; otherwise, returns kUnknown_SkColorType.
325 
326         @return  SkColorType of SkImage
327 
328         example: https://fiddle.skia.org/c/@Image_colorType
329     */
330     SkColorType colorType() const;
331 
332     /** Returns SkColorSpace, the range of colors, associated with SkImage.  The
333         reference count of SkColorSpace is unchanged. The returned SkColorSpace is
334         immutable.
335 
336         SkColorSpace returned was passed to an SkImage constructor,
337         or was parsed from encoded data. SkColorSpace returned may be ignored when SkImage
338         is drawn, depending on the capabilities of the SkSurface receiving the drawing.
339 
340         @return  SkColorSpace in SkImage, or nullptr
341 
342         example: https://fiddle.skia.org/c/@Image_colorSpace
343     */
344     SkColorSpace* colorSpace() const;
345 
346     /** Returns a smart pointer to SkColorSpace, the range of colors, associated with
347         SkImage.  The smart pointer tracks the number of objects sharing this
348         SkColorSpace reference so the memory is released when the owners destruct.
349 
350         The returned SkColorSpace is immutable.
351 
352         SkColorSpace returned was passed to an SkImage constructor,
353         or was parsed from encoded data. SkColorSpace returned may be ignored when SkImage
354         is drawn, depending on the capabilities of the SkSurface receiving the drawing.
355 
356         @return  SkColorSpace in SkImage, or nullptr, wrapped in a smart pointer
357 
358         example: https://fiddle.skia.org/c/@Image_refColorSpace
359     */
360     sk_sp<SkColorSpace> refColorSpace() const;
361 
362     /** Returns true if SkImage pixels represent transparency only. If true, each pixel
363         is packed in 8 bits as defined by kAlpha_8_SkColorType.
364 
365         @return  true if pixels represent a transparency mask
366 
367         example: https://fiddle.skia.org/c/@Image_isAlphaOnly
368     */
369     bool isAlphaOnly() const;
370 
371     /** Returns true if pixels ignore their alpha value and are treated as fully opaque.
372 
373         @return  true if SkAlphaType is kOpaque_SkAlphaType
374     */
isOpaque()375     bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }
376 
377     /**
378      *  Make a shader with the specified tiling and mipmap sampling.
379      */
380     sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions&,
381                                const SkMatrix* localMatrix = nullptr) const;
382     sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions& sampling,
383                                const SkMatrix& lm) const;
384     /** Defaults to clamp in both X and Y. */
385     sk_sp<SkShader> makeShader(const SkSamplingOptions& sampling, const SkMatrix& lm) const;
386     sk_sp<SkShader> makeShader(const SkSamplingOptions& sampling,
387                                const SkMatrix* lm = nullptr) const;
388 
389     /**
390      *  makeRawShader functions like makeShader, but for images that contain non-color data.
391      *  This includes images encoding things like normals, material properties (eg, roughness),
392      *  heightmaps, or any other purely mathematical data that happens to be stored in an image.
393      *  These types of images are useful with some programmable shaders (see: SkRuntimeEffect).
394      *
395      *  Raw image shaders work like regular image shaders (including filtering and tiling), with
396      *  a few major differences:
397      *    - No color space transformation is ever applied (the color space of the image is ignored).
398      *    - Images with an alpha type of kUnpremul are *not* automatically premultiplied.
399      *    - Bicubic filtering is not supported. If SkSamplingOptions::useCubic is true, these
400      *      factories will return nullptr.
401      */
402     sk_sp<SkShader> makeRawShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions&,
403                                   const SkMatrix* localMatrix = nullptr) const;
404     sk_sp<SkShader> makeRawShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions& sampling,
405                                   const SkMatrix& lm) const;
406     /** Defaults to clamp in both X and Y. */
407     sk_sp<SkShader> makeRawShader(const SkSamplingOptions& sampling, const SkMatrix& lm) const;
408     sk_sp<SkShader> makeRawShader(const SkSamplingOptions& sampling,
409                                   const SkMatrix* lm = nullptr) const;
410 
411     /** Copies SkImage pixel address, row bytes, and SkImageInfo to pixmap, if address
412         is available, and returns true. If pixel address is not available, return
413         false and leave pixmap unchanged.
414 
415         @param pixmap  storage for pixel state if pixels are readable; otherwise, ignored
416         @return        true if SkImage has direct access to pixels
417 
418         example: https://fiddle.skia.org/c/@Image_peekPixels
419     */
420     bool peekPixels(SkPixmap* pixmap) const;
421 
422     /** Returns true if the contents of SkImage was created on or uploaded to GPU memory,
423         and is available as a GPU texture.
424 
425         @return  true if SkImage is a GPU texture
426 
427         example: https://fiddle.skia.org/c/@Image_isTextureBacked
428     */
429     virtual bool isTextureBacked() const = 0;
430 
431     /** Returns an approximation of the amount of texture memory used by the image. Returns
432         zero if the image is not texture backed or if the texture has an external format.
433      */
434     virtual size_t textureSize() const = 0;
435 
436     /** Returns true if SkImage can be drawn on either raster surface or GPU surface.
437         If context is nullptr, tests if SkImage draws on raster surface;
438         otherwise, tests if SkImage draws on GPU surface associated with context.
439 
440         SkImage backed by GPU texture may become invalid if associated context is
441         invalid. lazy image may be invalid and may not draw to raster surface or
442         GPU surface or both.
443 
444         @param context  GPU context
445         @return         true if SkImage can be drawn
446 
447         example: https://fiddle.skia.org/c/@Image_isValid
448     */
449     virtual bool isValid(GrRecordingContext* context) const = 0;
450 
451     /** \enum SkImage::CachingHint
452         CachingHint selects whether Skia may internally cache SkBitmap generated by
453         decoding SkImage, or by copying SkImage from GPU to CPU. The default behavior
454         allows caching SkBitmap.
455 
456         Choose kDisallow_CachingHint if SkImage pixels are to be used only once, or
457         if SkImage pixels reside in a cache outside of Skia, or to reduce memory pressure.
458 
459         Choosing kAllow_CachingHint does not ensure that pixels will be cached.
460         SkImage pixels may not be cached if memory requirements are too large or
461         pixels are not accessible.
462     */
463     enum CachingHint {
464         kAllow_CachingHint,    //!< allows internally caching decoded and copied pixels
465         kDisallow_CachingHint, //!< disallows internally caching decoded and copied pixels
466     };
467 
468     /** Copies SkRect of pixels from SkImage to dstPixels. Copy starts at offset (srcX, srcY),
469         and does not exceed SkImage (width(), height()).
470 
471         Graphite has deprecated this API in favor of the equivalent asynchronous API on
472         skgpu::graphite::Context (with an optional explicit synchonization).
473 
474         dstInfo specifies width, height, SkColorType, SkAlphaType, and SkColorSpace of
475         destination. dstRowBytes specifies the gap from one destination row to the next.
476         Returns true if pixels are copied. Returns false if:
477         - dstInfo.addr() equals nullptr
478         - dstRowBytes is less than dstInfo.minRowBytes()
479         - SkPixelRef is nullptr
480 
481         Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
482         kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
483         If SkImage SkColorType is kGray_8_SkColorType, dstInfo.colorSpace() must match.
484         If SkImage SkAlphaType is kOpaque_SkAlphaType, dstInfo.alphaType() must
485         match. If SkImage SkColorSpace is nullptr, dstInfo.colorSpace() must match. Returns
486         false if pixel conversion is not possible.
487 
488         srcX and srcY may be negative to copy only top or left of source. Returns
489         false if width() or height() is zero or negative.
490         Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().
491 
492         If cachingHint is kAllow_CachingHint, pixels may be retained locally.
493         If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
494 
495         @param context      the GrDirectContext in play, if it exists
496         @param dstInfo      destination width, height, SkColorType, SkAlphaType, SkColorSpace
497         @param dstPixels    destination pixel storage
498         @param dstRowBytes  destination row length
499         @param srcX         column index whose absolute value is less than width()
500         @param srcY         row index whose absolute value is less than height()
501         @param cachingHint  whether the pixels should be cached locally
502         @return             true if pixels are copied to dstPixels
503     */
504     bool readPixels(GrDirectContext* context,
505                     const SkImageInfo& dstInfo,
506                     void* dstPixels,
507                     size_t dstRowBytes,
508                     int srcX, int srcY,
509                     CachingHint cachingHint = kAllow_CachingHint) const;
510 
511     /** Copies a SkRect of pixels from SkImage to dst. Copy starts at (srcX, srcY), and
512         does not exceed SkImage (width(), height()).
513 
514         Graphite has deprecated this API in favor of the equivalent asynchronous API on
515         skgpu::graphite::Context (with an optional explicit synchonization).
516 
517         dst specifies width, height, SkColorType, SkAlphaType, SkColorSpace, pixel storage,
518         and row bytes of destination. dst.rowBytes() specifics the gap from one destination
519         row to the next. Returns true if pixels are copied. Returns false if:
520         - dst pixel storage equals nullptr
521         - dst.rowBytes is less than SkImageInfo::minRowBytes
522         - SkPixelRef is nullptr
523 
524         Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
525         kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
526         If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
527         If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
528         match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
529         false if pixel conversion is not possible.
530 
531         srcX and srcY may be negative to copy only top or left of source. Returns
532         false if width() or height() is zero or negative.
533         Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().
534 
535         If cachingHint is kAllow_CachingHint, pixels may be retained locally.
536         If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
537 
538         @param context      the GrDirectContext in play, if it exists
539         @param dst          destination SkPixmap: SkImageInfo, pixels, row bytes
540         @param srcX         column index whose absolute value is less than width()
541         @param srcY         row index whose absolute value is less than height()
542         @param cachingHint  whether the pixels should be cached locallyZ
543         @return             true if pixels are copied to dst
544     */
545     bool readPixels(GrDirectContext* context,
546                     const SkPixmap& dst,
547                     int srcX,
548                     int srcY,
549                     CachingHint cachingHint = kAllow_CachingHint) const;
550 
551 #ifndef SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API
552     /** Deprecated. Use the variants that accept a GrDirectContext. */
553     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
554                     int srcX, int srcY, CachingHint cachingHint = kAllow_CachingHint) const;
555     bool readPixels(const SkPixmap& dst, int srcX, int srcY,
556                     CachingHint cachingHint = kAllow_CachingHint) const;
557 #endif
558 
559     /** The result from asyncRescaleAndReadPixels() or asyncRescaleAndReadPixelsYUV420(). */
560     class AsyncReadResult {
561     public:
562         AsyncReadResult(const AsyncReadResult&) = delete;
563         AsyncReadResult(AsyncReadResult&&) = delete;
564         AsyncReadResult& operator=(const AsyncReadResult&) = delete;
565         AsyncReadResult& operator=(AsyncReadResult&&) = delete;
566 
567         virtual ~AsyncReadResult() = default;
568         /** Returns how many planes of data are in the result. e.g. 3 for YUV data. */
569         virtual int count() const = 0;
570         /** Returns the raw pixel data for a given plane.
571          *
572          * It will be organized as per the dst SkImageInfo passed in to the async read call.
573          *
574          * Clients may wish to create an SkPixmap with this data using the dst SkImageInfo
575          * and rowBytes(i).
576          */
577         virtual const void* data(int i) const = 0;
578         /** Returns how many bytes correspond to a single row of image data */
579         virtual size_t rowBytes(int i) const = 0;
580 
581     protected:
582         AsyncReadResult() = default;
583     };
584 
585     /** Client-provided context that is passed to client-provided ReadPixelsContext. */
586     using ReadPixelsContext = void*;
587 
588     /**  Client-provided callback to asyncRescaleAndReadPixels() or
589          asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure.
590      */
591     using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>);
592 
593     enum class RescaleGamma : bool { kSrc, kLinear };
594 
595     enum class RescaleMode {
596         kNearest,
597         kLinear,
598         kRepeatedLinear,
599         kRepeatedCubic,
600     };
601 
602     /** Makes image pixel data available to caller, possibly asynchronously. It can also rescale
603         the image pixels.
604 
605         Currently asynchronous reads are only supported in the Ganesh GPU backend and only when the
606         underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all
607         other cases this operates synchronously.
608 
609         For the Graphite backend this API has been deprecated in favor of the equivalent API
610         on skgpu::graphite::Context.
611 
612         Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is
613         rescaled to the size indicated by 'info', is then converted to the color space, color type,
614         and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the image
615         causes failure.
616 
617         When the pixel data is ready the caller's ReadPixelsCallback is called with a
618         AsyncReadResult containing pixel data in the requested color type, alpha type, and color
619         space. The AsyncReadResult will have count() == 1. Upon failure the callback is called with
620         nullptr for AsyncReadResult. For a GPU image this flushes work but a submit must occur to
621         guarantee a finite time before the callback is called.
622 
623         The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
624         is GPU-backed the data is immediately invalidated if the context is abandoned or
625         destroyed.
626 
627         @param info            info of the requested pixels
628         @param srcRect         subrectangle of image to read
629         @param rescaleGamma    controls whether rescaling is done in the image's gamma or whether
630                                the source data is transformed to a linear gamma before rescaling.
631         @param rescaleMode     controls the technique (and cost) of the rescaling
632         @param callback        function to call with result of the read
633         @param context         passed to callback
634     */
635     void asyncRescaleAndReadPixels(const SkImageInfo& info,
636                                    const SkIRect& srcRect,
637                                    RescaleGamma rescaleGamma,
638                                    RescaleMode rescaleMode,
639                                    ReadPixelsCallback callback,
640                                    ReadPixelsContext context) const;
641 
642     /**
643         Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The
644         RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three
645         planes ordered y, u, v. The u and v planes are half the width and height of the resized
646         rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize'
647         width and height are not even. A 'srcRect' that is not contained by the bounds of the
648         image causes failure.
649 
650         When the pixel data is ready the caller's ReadPixelsCallback is called with a
651         AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3.
652         Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU image this
653         flushes work but a submit must occur to guarantee a finite time before the callback is
654         called.
655 
656         The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
657         is GPU-backed the data is immediately invalidated if the context is abandoned or
658         destroyed.
659 
660         @param yuvColorSpace  The transformation from RGB to YUV. Applied to the resized image
661                               after it is converted to dstColorSpace.
662         @param dstColorSpace  The color space to convert the resized image to, after rescaling.
663         @param srcRect        The portion of the image to rescale and convert to YUV planes.
664         @param dstSize        The size to rescale srcRect to
665         @param rescaleGamma   controls whether rescaling is done in the image's gamma or whether
666                               the source data is transformed to a linear gamma before rescaling.
667         @param rescaleMode    controls the technique (and cost) of the rescaling
668         @param callback       function to call with the planar read result
669         @param context        passed to callback
670      */
671     void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
672                                          sk_sp<SkColorSpace> dstColorSpace,
673                                          const SkIRect& srcRect,
674                                          const SkISize& dstSize,
675                                          RescaleGamma rescaleGamma,
676                                          RescaleMode rescaleMode,
677                                          ReadPixelsCallback callback,
678                                          ReadPixelsContext context) const;
679 
680     /**
681      * Identical to asyncRescaleAndReadPixelsYUV420 but a fourth plane is returned in the
682      * AsyncReadResult passed to 'callback'. The fourth plane contains the alpha chanel at the
683      * same full resolution as the Y plane.
684      */
685     void asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace,
686                                           sk_sp<SkColorSpace> dstColorSpace,
687                                           const SkIRect& srcRect,
688                                           const SkISize& dstSize,
689                                           RescaleGamma rescaleGamma,
690                                           RescaleMode rescaleMode,
691                                           ReadPixelsCallback callback,
692                                           ReadPixelsContext context) const;
693 
694     /** Copies SkImage to dst, scaling pixels to fit dst.width() and dst.height(), and
695         converting pixels to match dst.colorType() and dst.alphaType(). Returns true if
696         pixels are copied. Returns false if dst.addr() is nullptr, or dst.rowBytes() is
697         less than dst SkImageInfo::minRowBytes.
698 
699         Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
700         kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
701         If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
702         If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
703         match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
704         false if pixel conversion is not possible.
705 
706         If cachingHint is kAllow_CachingHint, pixels may be retained locally.
707         If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
708 
709         @param dst            destination SkPixmap: SkImageInfo, pixels, row bytes
710         @return               true if pixels are scaled to fit dst
711     */
712     bool scalePixels(const SkPixmap& dst, const SkSamplingOptions&,
713                      CachingHint cachingHint = kAllow_CachingHint) const;
714 
715     /**
716      * Create a new image by copying this image and scaling to fit the ImageInfo's dimensions
717      * and converting the pixels into the ImageInfo's ColorInfo.
718      * This is done retaining the domain (backend) of the image (e.g. gpu, raster)
719      *
720      * The Recorder parameter is required if the original image was created on a graphite Recorder,
721      * but must be nullptr if it was create in some other way (e.g. GrContext, raster, deferred).
722      *
723      * return nullptr if the requested ColorInfo is not supported,  its dimesions are out of range,
724      *  or if the recorder is null on a graphite Image.
725      */
726     sk_sp<SkImage> makeScaled(skgpu::graphite::Recorder*,
727                               const SkImageInfo&,
728                               const SkSamplingOptions&) const;
729 
makeScaled(const SkImageInfo & info,const SkSamplingOptions & sampling)730     sk_sp<SkImage> makeScaled(const SkImageInfo& info,
731                               const SkSamplingOptions& sampling) const {
732         return this->makeScaled(nullptr, info, sampling);
733     }
734 
735     /** Returns encoded SkImage pixels as SkData, if SkImage was created from supported
736         encoded stream format. Platform support for formats vary and may require building
737         with one or more of: SK_ENCODE_JPEG, SK_ENCODE_PNG, SK_ENCODE_WEBP.
738 
739         Returns nullptr if SkImage contents are not encoded.
740 
741         @return  encoded SkImage, or nullptr
742 
743         example: https://fiddle.skia.org/c/@Image_refEncodedData
744     */
745     sk_sp<SkData> refEncodedData() const;
746 
747     /** Returns subset of this image.
748 
749         Returns nullptr if any of the following are true:
750           - Subset is empty
751           - Subset is not contained inside the image's bounds
752           - Pixels in the source image could not be read or copied
753           - This image is texture-backed and the provided context is null or does not match
754             the source image's context.
755 
756         If the source image was texture-backed, the resulting image will be texture-backed also.
757         Otherwise, the returned image will be raster-backed.
758 
759         @param direct  the GrDirectContext of the source image (nullptr is ok if the source image
760                        is not texture-backed).
761         @param subset  bounds of returned SkImage
762         @return        the subsetted image, or nullptr
763 
764         example: https://fiddle.skia.org/c/@Image_makeSubset
765     */
766     virtual sk_sp<SkImage> makeSubset(GrDirectContext* direct, const SkIRect& subset) const = 0;
767 
768     struct RequiredProperties {
769         bool fMipmapped;
770 
771         bool operator==(const RequiredProperties& other) const {
772             return fMipmapped == other.fMipmapped;
773         }
774 
775         bool operator!=(const RequiredProperties& other) const { return !(*this == other); }
776 
777         bool operator<(const RequiredProperties& other) const {
778             return fMipmapped < other.fMipmapped;
779         }
780     };
781 
782     /** Returns subset of this image.
783 
784         Returns nullptr if any of the following are true:
785           - Subset is empty
786           - Subset is not contained inside the image's bounds
787           - Pixels in the image could not be read or copied
788           - This image is texture-backed and the provided context is null or does not match
789             the source image's context.
790 
791         If the source image was texture-backed, the resulting image will be texture-backed also.
792         Otherwise, the returned image will be raster-backed.
793 
794         @param recorder            the recorder of the source image (nullptr is ok if the
795                                    source image was texture-backed).
796         @param subset              bounds of returned SkImage
797         @param RequiredProperties  properties the returned SkImage must possess (e.g. mipmaps)
798         @return                    the subsetted image, or nullptr
799     */
800     virtual sk_sp<SkImage> makeSubset(skgpu::graphite::Recorder*,
801                                       const SkIRect& subset,
802                                       RequiredProperties) const = 0;
803 
804     /**
805      *  Returns true if the image has mipmap levels.
806      */
807     bool hasMipmaps() const;
808 
809     /**
810      *  Returns true if the image holds protected content.
811      */
812     bool isProtected() const;
813 
814     /**
815      *  Returns an image with the same "base" pixels as the this image, but with mipmap levels
816      *  automatically generated and attached.
817      */
818     sk_sp<SkImage> withDefaultMipmaps() const;
819 
820     /** Returns raster image or lazy image. Copies SkImage backed by GPU texture into
821         CPU memory if needed. Returns original SkImage if decoded in raster bitmap,
822         or if encoded in a stream.
823 
824         Returns nullptr if backed by GPU texture and copy fails.
825 
826         @return  raster image, lazy image, or nullptr
827 
828         example: https://fiddle.skia.org/c/@Image_makeNonTextureImage
829     */
830     sk_sp<SkImage> makeNonTextureImage(GrDirectContext* = nullptr) const;
831 
832     /** Returns raster image. Copies SkImage backed by GPU texture into CPU memory,
833         or decodes SkImage from lazy image. Returns original SkImage if decoded in
834         raster bitmap.
835 
836         Returns nullptr if copy, decode, or pixel read fails.
837 
838         If cachingHint is kAllow_CachingHint, pixels may be retained locally.
839         If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
840 
841         @return  raster image, or nullptr
842 
843         example: https://fiddle.skia.org/c/@Image_makeRasterImage
844     */
845     sk_sp<SkImage> makeRasterImage(GrDirectContext*,
846                                    CachingHint cachingHint = kDisallow_CachingHint) const;
847 
848 #if !defined(SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API)
849     sk_sp<SkImage> makeRasterImage(CachingHint cachingHint = kDisallow_CachingHint) const {
850         return this->makeRasterImage(nullptr, cachingHint);
851     }
852 #endif
853 
854     /** Deprecated.
855      */
856     enum LegacyBitmapMode {
857         kRO_LegacyBitmapMode, //!< returned bitmap is read-only and immutable
858     };
859 
860     /** Deprecated.
861         Creates raster SkBitmap with same pixels as SkImage. If legacyBitmapMode is
862         kRO_LegacyBitmapMode, returned bitmap is read-only and immutable.
863         Returns true if SkBitmap is stored in bitmap. Returns false and resets bitmap if
864         SkBitmap write did not succeed.
865 
866         @param bitmap            storage for legacy SkBitmap
867         @param legacyBitmapMode  bitmap is read-only and immutable
868         @return                  true if SkBitmap was created
869     */
870     bool asLegacyBitmap(SkBitmap* bitmap,
871                         LegacyBitmapMode legacyBitmapMode = kRO_LegacyBitmapMode) const;
872 
873     /** Returns true if SkImage is backed by an image-generator or other service that creates
874         and caches its pixels or texture on-demand.
875 
876         @return  true if SkImage is created as needed
877 
878         example: https://fiddle.skia.org/c/@Image_isLazyGenerated_a
879         example: https://fiddle.skia.org/c/@Image_isLazyGenerated_b
880     */
881     virtual bool isLazyGenerated() const = 0;
882 
883     /** Creates SkImage in target SkColorSpace.
884         Returns nullptr if SkImage could not be created.
885 
886         Returns original SkImage if it is in target SkColorSpace.
887         Otherwise, converts pixels from SkImage SkColorSpace to target SkColorSpace.
888         If SkImage colorSpace() returns nullptr, SkImage SkColorSpace is assumed to be sRGB.
889 
890         If this image is texture-backed, the context parameter is required and must match the
891         context of the source image.
892 
893         @param direct  The GrDirectContext in play, if it exists
894         @param target  SkColorSpace describing color range of returned SkImage
895         @return        created SkImage in target SkColorSpace
896 
897         example: https://fiddle.skia.org/c/@Image_makeColorSpace
898     */
899     virtual sk_sp<SkImage> makeColorSpace(GrDirectContext* direct,
900                                           sk_sp<SkColorSpace> target) const = 0;
901 
902     /** Creates SkImage in target SkColorSpace.
903         Returns nullptr if SkImage could not be created.
904 
905         Returns original SkImage if it is in target SkColorSpace.
906         Otherwise, converts pixels from SkImage SkColorSpace to target SkColorSpace.
907         If SkImage colorSpace() returns nullptr, SkImage SkColorSpace is assumed to be sRGB.
908 
909         If this image is graphite-backed, the recorder parameter is required.
910 
911         @param targetColorSpace    SkColorSpace describing color range of returned SkImage
912         @param recorder            The Recorder in which to create the new image
913         @param RequiredProperties  properties the returned SkImage must possess (e.g. mipmaps)
914         @return                    created SkImage in target SkColorSpace
915     */
916     virtual sk_sp<SkImage> makeColorSpace(skgpu::graphite::Recorder*,
917                                           sk_sp<SkColorSpace> targetColorSpace,
918                                           RequiredProperties) const = 0;
919 
920     /** Experimental.
921         Creates SkImage in target SkColorType and SkColorSpace.
922         Returns nullptr if SkImage could not be created.
923 
924         Returns original SkImage if it is in target SkColorType and SkColorSpace.
925 
926         If this image is texture-backed, the context parameter is required and must match the
927         context of the source image.
928 
929         @param direct           The GrDirectContext in play, if it exists
930         @param targetColorType  SkColorType of returned SkImage
931         @param targetColorSpace SkColorSpace of returned SkImage
932         @return                 created SkImage in target SkColorType and SkColorSpace
933     */
934     virtual sk_sp<SkImage> makeColorTypeAndColorSpace(GrDirectContext* direct,
935                                                       SkColorType targetColorType,
936                                                       sk_sp<SkColorSpace> targetCS) const = 0;
937 
938     /** Experimental.
939         Creates SkImage in target SkColorType and SkColorSpace.
940         Returns nullptr if SkImage could not be created.
941 
942         Returns original SkImage if it is in target SkColorType and SkColorSpace.
943 
944         If this image is graphite-backed, the recorder parameter is required.
945 
946         @param targetColorType     SkColorType of returned SkImage
947         @param targetColorSpace    SkColorSpace of returned SkImage
948         @param recorder            The Recorder in which to create the new image
949         @param RequiredProperties  properties the returned SkImage must possess (e.g. mipmaps)
950         @return                    created SkImage in target SkColorType and SkColorSpace
951     */
952     virtual sk_sp<SkImage> makeColorTypeAndColorSpace(skgpu::graphite::Recorder*,
953                                                       SkColorType targetColorType,
954                                                       sk_sp<SkColorSpace> targetColorSpace,
955                                                       RequiredProperties) const = 0;
956 
957     /** Creates a new SkImage identical to this one, but with a different SkColorSpace.
958         This does not convert the underlying pixel data, so the resulting image will draw
959         differently.
960     */
961     sk_sp<SkImage> reinterpretColorSpace(sk_sp<SkColorSpace> newColorSpace) const;
962 
963 private:
964     SkImage(const SkImageInfo& info, uint32_t uniqueID);
965 
966     friend class SkBitmap;
967     friend class SkImage_Base;   // for private ctor
968     friend class SkImage_Raster; // for withMipmaps
969     friend class SkMipmapBuilder;
970 
971     SkImageInfo     fInfo;
972     const uint32_t  fUniqueID;
973 
974     sk_sp<SkImage> withMipmaps(sk_sp<SkMipmap>) const;
975 
976     using INHERITED = SkRefCnt;
977 };
978 
979 #endif
980