Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/core/SkImage.h
Line
Count
Source (jump to first uncovered line)
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
    */
279
75.7k
    const SkImageInfo& imageInfo() const { return fInfo; }
280
281
    /** Returns pixel count in each row.
282
283
        @return  pixel width in SkImage
284
    */
285
438k
    int width() const { return fInfo.width(); }
286
287
    /** Returns pixel row count.
288
289
        @return  pixel height in SkImage
290
    */
291
438k
    int height() const { return fInfo.height(); }
292
293
    /** Returns SkISize { width(), height() }.
294
295
        @return  integral size of width() and height()
296
    */
297
118k
    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
    */
303
99.1k
    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
    */
311
36.3k
    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
    */
375
120k
    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
        dstInfo specifies width, height, SkColorType, SkAlphaType, and SkColorSpace of
472
        destination. dstRowBytes specifies the gap from one destination row to the next.
473
        Returns true if pixels are copied. Returns false if:
474
        - dstInfo.addr() equals nullptr
475
        - dstRowBytes is less than dstInfo.minRowBytes()
476
        - SkPixelRef is nullptr
477
478
        Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
479
        kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
480
        If SkImage SkColorType is kGray_8_SkColorType, dstInfo.colorSpace() must match.
481
        If SkImage SkAlphaType is kOpaque_SkAlphaType, dstInfo.alphaType() must
482
        match. If SkImage SkColorSpace is nullptr, dstInfo.colorSpace() must match. Returns
483
        false if pixel conversion is not possible.
484
485
        srcX and srcY may be negative to copy only top or left of source. Returns
486
        false if width() or height() is zero or negative.
487
        Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().
488
489
        If cachingHint is kAllow_CachingHint, pixels may be retained locally.
490
        If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
491
492
        @param context      the GrDirectContext in play, if it exists
493
        @param dstInfo      destination width, height, SkColorType, SkAlphaType, SkColorSpace
494
        @param dstPixels    destination pixel storage
495
        @param dstRowBytes  destination row length
496
        @param srcX         column index whose absolute value is less than width()
497
        @param srcY         row index whose absolute value is less than height()
498
        @param cachingHint  whether the pixels should be cached locally
499
        @return             true if pixels are copied to dstPixels
500
    */
501
    bool readPixels(GrDirectContext* context,
502
                    const SkImageInfo& dstInfo,
503
                    void* dstPixels,
504
                    size_t dstRowBytes,
505
                    int srcX, int srcY,
506
                    CachingHint cachingHint = kAllow_CachingHint) const;
507
508
    /** Copies a SkRect of pixels from SkImage to dst. Copy starts at (srcX, srcY), and
509
        does not exceed SkImage (width(), height()).
510
511
        dst specifies width, height, SkColorType, SkAlphaType, SkColorSpace, pixel storage,
512
        and row bytes of destination. dst.rowBytes() specifics the gap from one destination
513
        row to the next. Returns true if pixels are copied. Returns false if:
514
        - dst pixel storage equals nullptr
515
        - dst.rowBytes is less than SkImageInfo::minRowBytes
516
        - SkPixelRef is nullptr
517
518
        Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
519
        kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
520
        If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
521
        If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
522
        match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
523
        false if pixel conversion is not possible.
524
525
        srcX and srcY may be negative to copy only top or left of source. Returns
526
        false if width() or height() is zero or negative.
527
        Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().
528
529
        If cachingHint is kAllow_CachingHint, pixels may be retained locally.
530
        If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
531
532
        @param context      the GrDirectContext in play, if it exists
533
        @param dst          destination SkPixmap: SkImageInfo, pixels, row bytes
534
        @param srcX         column index whose absolute value is less than width()
535
        @param srcY         row index whose absolute value is less than height()
536
        @param cachingHint  whether the pixels should be cached locallyZ
537
        @return             true if pixels are copied to dst
538
    */
539
    bool readPixels(GrDirectContext* context,
540
                    const SkPixmap& dst,
541
                    int srcX,
542
                    int srcY,
543
                    CachingHint cachingHint = kAllow_CachingHint) const;
544
545
#if defined(GRAPHITE_TEST_UTILS)
546
    bool readPixelsGraphite(skgpu::graphite::Recorder*,
547
                            const SkPixmap& dst,
548
                            int srcX,
549
                            int srcY) const;
550
#endif
551
552
#ifndef SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API
553
    /** Deprecated. Use the variants that accept a GrDirectContext. */
554
    bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
555
                    int srcX, int srcY, CachingHint cachingHint = kAllow_CachingHint) const;
556
    bool readPixels(const SkPixmap& dst, int srcX, int srcY,
557
                    CachingHint cachingHint = kAllow_CachingHint) const;
558
#endif
559
560
    /** The result from asyncRescaleAndReadPixels() or asyncRescaleAndReadPixelsYUV420(). */
561
    class AsyncReadResult {
562
    public:
563
        AsyncReadResult(const AsyncReadResult&) = delete;
564
        AsyncReadResult(AsyncReadResult&&) = delete;
565
        AsyncReadResult& operator=(const AsyncReadResult&) = delete;
566
        AsyncReadResult& operator=(AsyncReadResult&&) = delete;
567
568
0
        virtual ~AsyncReadResult() = default;
569
        virtual int count() const = 0;
570
        virtual const void* data(int i) const = 0;
571
        virtual size_t rowBytes(int i) const = 0;
572
573
    protected:
574
0
        AsyncReadResult() = default;
575
    };
576
577
    /** Client-provided context that is passed to client-provided ReadPixelsContext. */
578
    using ReadPixelsContext = void*;
579
580
    /**  Client-provided callback to asyncRescaleAndReadPixels() or
581
         asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure.
582
     */
583
    using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>);
584
585
    enum class RescaleGamma : bool { kSrc, kLinear };
586
587
    enum class RescaleMode {
588
        kNearest,
589
        kLinear,
590
        kRepeatedLinear,
591
        kRepeatedCubic,
592
    };
593
594
    /** Makes image pixel data available to caller, possibly asynchronously. It can also rescale
595
        the image pixels.
596
597
        Currently asynchronous reads are only supported on the GPU backend and only when the
598
        underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all
599
        other cases this operates synchronously.
600
601
        Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is
602
        rescaled to the size indicated by 'info', is then converted to the color space, color type,
603
        and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the image
604
        causes failure.
605
606
        When the pixel data is ready the caller's ReadPixelsCallback is called with a
607
        AsyncReadResult containing pixel data in the requested color type, alpha type, and color
608
        space. The AsyncReadResult will have count() == 1. Upon failure the callback is called with
609
        nullptr for AsyncReadResult. For a GPU image this flushes work but a submit must occur to
610
        guarantee a finite time before the callback is called.
611
612
        The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
613
        is GPU-backed the data is immediately invalidated if the context is abandoned or
614
        destroyed.
615
616
        @param info            info of the requested pixels
617
        @param srcRect         subrectangle of image to read
618
        @param rescaleGamma    controls whether rescaling is done in the image's gamma or whether
619
                               the source data is transformed to a linear gamma before rescaling.
620
        @param rescaleMode     controls the technique (and cost) of the rescaling
621
        @param callback        function to call with result of the read
622
        @param context         passed to callback
623
    */
624
    void asyncRescaleAndReadPixels(const SkImageInfo& info,
625
                                   const SkIRect& srcRect,
626
                                   RescaleGamma rescaleGamma,
627
                                   RescaleMode rescaleMode,
628
                                   ReadPixelsCallback callback,
629
                                   ReadPixelsContext context) const;
630
631
    /**
632
        Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The
633
        RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three
634
        planes ordered y, u, v. The u and v planes are half the width and height of the resized
635
        rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize'
636
        width and height are not even. A 'srcRect' that is not contained by the bounds of the
637
        image causes failure.
638
639
        When the pixel data is ready the caller's ReadPixelsCallback is called with a
640
        AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3.
641
        Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU image this
642
        flushes work but a submit must occur to guarantee a finite time before the callback is
643
        called.
644
645
        The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
646
        is GPU-backed the data is immediately invalidated if the context is abandoned or
647
        destroyed.
648
649
        @param yuvColorSpace  The transformation from RGB to YUV. Applied to the resized image
650
                              after it is converted to dstColorSpace.
651
        @param dstColorSpace  The color space to convert the resized image to, after rescaling.
652
        @param srcRect        The portion of the image to rescale and convert to YUV planes.
653
        @param dstSize        The size to rescale srcRect to
654
        @param rescaleGamma   controls whether rescaling is done in the image's gamma or whether
655
                              the source data is transformed to a linear gamma before rescaling.
656
        @param rescaleMode    controls the technique (and cost) of the rescaling
657
        @param callback       function to call with the planar read result
658
        @param context        passed to callback
659
     */
660
    void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
661
                                         sk_sp<SkColorSpace> dstColorSpace,
662
                                         const SkIRect& srcRect,
663
                                         const SkISize& dstSize,
664
                                         RescaleGamma rescaleGamma,
665
                                         RescaleMode rescaleMode,
666
                                         ReadPixelsCallback callback,
667
                                         ReadPixelsContext context) const;
668
669
    /**
670
     * Identical to asyncRescaleAndReadPixelsYUV420 but a fourth plane is returned in the
671
     * AsyncReadResult passed to 'callback'. The fourth plane contains the alpha chanel at the
672
     * same full resolution as the Y plane.
673
     */
674
    void asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace,
675
                                          sk_sp<SkColorSpace> dstColorSpace,
676
                                          const SkIRect& srcRect,
677
                                          const SkISize& dstSize,
678
                                          RescaleGamma rescaleGamma,
679
                                          RescaleMode rescaleMode,
680
                                          ReadPixelsCallback callback,
681
                                          ReadPixelsContext context) const;
682
683
    /** Copies SkImage to dst, scaling pixels to fit dst.width() and dst.height(), and
684
        converting pixels to match dst.colorType() and dst.alphaType(). Returns true if
685
        pixels are copied. Returns false if dst.addr() is nullptr, or dst.rowBytes() is
686
        less than dst SkImageInfo::minRowBytes.
687
688
        Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
689
        kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
690
        If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
691
        If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
692
        match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
693
        false if pixel conversion is not possible.
694
695
        If cachingHint is kAllow_CachingHint, pixels may be retained locally.
696
        If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
697
698
        @param dst            destination SkPixmap: SkImageInfo, pixels, row bytes
699
        @return               true if pixels are scaled to fit dst
700
    */
701
    bool scalePixels(const SkPixmap& dst, const SkSamplingOptions&,
702
                     CachingHint cachingHint = kAllow_CachingHint) const;
703
704
    /** Returns encoded SkImage pixels as SkData, if SkImage was created from supported
705
        encoded stream format. Platform support for formats vary and may require building
706
        with one or more of: SK_ENCODE_JPEG, SK_ENCODE_PNG, SK_ENCODE_WEBP.
707
708
        Returns nullptr if SkImage contents are not encoded.
709
710
        @return  encoded SkImage, or nullptr
711
712
        example: https://fiddle.skia.org/c/@Image_refEncodedData
713
    */
714
    sk_sp<SkData> refEncodedData() const;
715
716
    /** Returns subset of this image.
717
718
        Returns nullptr if any of the following are true:
719
          - Subset is empty
720
          - Subset is not contained inside the image's bounds
721
          - Pixels in the source image could not be read or copied
722
          - This image is texture-backed and the provided context is null or does not match
723
            the source image's context.
724
725
        If the source image was texture-backed, the resulting image will be texture-backed also.
726
        Otherwise, the returned image will be raster-backed.
727
728
        @param direct  the GrDirectContext of the source image (nullptr is ok if the source image
729
                       is not texture-backed).
730
        @param subset  bounds of returned SkImage
731
        @return        the subsetted image, or nullptr
732
733
        example: https://fiddle.skia.org/c/@Image_makeSubset
734
    */
735
    virtual sk_sp<SkImage> makeSubset(GrDirectContext* direct, const SkIRect& subset) const = 0;
736
737
    struct RequiredProperties {
738
        bool fMipmapped;
739
740
0
        bool operator==(const RequiredProperties& other) const {
741
0
            return fMipmapped == other.fMipmapped;
742
0
        }
743
744
0
        bool operator!=(const RequiredProperties& other) const { return !(*this == other); }
745
746
0
        bool operator<(const RequiredProperties& other) const {
747
0
            return fMipmapped < other.fMipmapped;
748
0
        }
749
    };
750
751
    /** Returns subset of this image.
752
753
        Returns nullptr if any of the following are true:
754
          - Subset is empty
755
          - Subset is not contained inside the image's bounds
756
          - Pixels in the image could not be read or copied
757
          - This image is texture-backed and the provided context is null or does not match
758
            the source image's context.
759
760
        If the source image was texture-backed, the resulting image will be texture-backed also.
761
        Otherwise, the returned image will be raster-backed.
762
763
        @param recorder            the recorder of the source image (nullptr is ok if the
764
                                   source image was texture-backed).
765
        @param subset              bounds of returned SkImage
766
        @param RequiredProperties  properties the returned SkImage must possess (e.g. mipmaps)
767
        @return                    the subsetted image, or nullptr
768
    */
769
    virtual sk_sp<SkImage> makeSubset(skgpu::graphite::Recorder*,
770
                                      const SkIRect& subset,
771
                                      RequiredProperties) const = 0;
772
773
    /**
774
     *  Returns true if the image has mipmap levels.
775
     */
776
    bool hasMipmaps() const;
777
778
    /**
779
     *  Returns true if the image holds protected content.
780
     */
781
    bool isProtected() const;
782
783
    /**
784
     *  Returns an image with the same "base" pixels as the this image, but with mipmap levels
785
     *  automatically generated and attached.
786
     */
787
    sk_sp<SkImage> withDefaultMipmaps() const;
788
789
    /** Returns raster image or lazy image. Copies SkImage backed by GPU texture into
790
        CPU memory if needed. Returns original SkImage if decoded in raster bitmap,
791
        or if encoded in a stream.
792
793
        Returns nullptr if backed by GPU texture and copy fails.
794
795
        @return  raster image, lazy image, or nullptr
796
797
        example: https://fiddle.skia.org/c/@Image_makeNonTextureImage
798
    */
799
    sk_sp<SkImage> makeNonTextureImage(GrDirectContext* = nullptr) const;
800
801
    /** Returns raster image. Copies SkImage backed by GPU texture into CPU memory,
802
        or decodes SkImage from lazy image. Returns original SkImage if decoded in
803
        raster bitmap.
804
805
        Returns nullptr if copy, decode, or pixel read fails.
806
807
        If cachingHint is kAllow_CachingHint, pixels may be retained locally.
808
        If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
809
810
        @return  raster image, or nullptr
811
812
        example: https://fiddle.skia.org/c/@Image_makeRasterImage
813
    */
814
    sk_sp<SkImage> makeRasterImage(GrDirectContext*,
815
                                   CachingHint cachingHint = kDisallow_CachingHint) const;
816
817
#if !defined(SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API)
818
3.02k
    sk_sp<SkImage> makeRasterImage(CachingHint cachingHint = kDisallow_CachingHint) const {
819
3.02k
        return this->makeRasterImage(nullptr, cachingHint);
820
3.02k
    }
821
#endif
822
823
    /** Deprecated.
824
     */
825
    enum LegacyBitmapMode {
826
        kRO_LegacyBitmapMode, //!< returned bitmap is read-only and immutable
827
    };
828
829
    /** Deprecated.
830
        Creates raster SkBitmap with same pixels as SkImage. If legacyBitmapMode is
831
        kRO_LegacyBitmapMode, returned bitmap is read-only and immutable.
832
        Returns true if SkBitmap is stored in bitmap. Returns false and resets bitmap if
833
        SkBitmap write did not succeed.
834
835
        @param bitmap            storage for legacy SkBitmap
836
        @param legacyBitmapMode  bitmap is read-only and immutable
837
        @return                  true if SkBitmap was created
838
    */
839
    bool asLegacyBitmap(SkBitmap* bitmap,
840
                        LegacyBitmapMode legacyBitmapMode = kRO_LegacyBitmapMode) const;
841
842
    /** Returns true if SkImage is backed by an image-generator or other service that creates
843
        and caches its pixels or texture on-demand.
844
845
        @return  true if SkImage is created as needed
846
847
        example: https://fiddle.skia.org/c/@Image_isLazyGenerated_a
848
        example: https://fiddle.skia.org/c/@Image_isLazyGenerated_b
849
    */
850
    virtual bool isLazyGenerated() const = 0;
851
852
    /** Creates SkImage in target SkColorSpace.
853
        Returns nullptr if SkImage could not be created.
854
855
        Returns original SkImage if it is in target SkColorSpace.
856
        Otherwise, converts pixels from SkImage SkColorSpace to target SkColorSpace.
857
        If SkImage colorSpace() returns nullptr, SkImage SkColorSpace is assumed to be sRGB.
858
859
        If this image is texture-backed, the context parameter is required and must match the
860
        context of the source image.
861
862
        @param direct  The GrDirectContext in play, if it exists
863
        @param target  SkColorSpace describing color range of returned SkImage
864
        @return        created SkImage in target SkColorSpace
865
866
        example: https://fiddle.skia.org/c/@Image_makeColorSpace
867
    */
868
    virtual sk_sp<SkImage> makeColorSpace(GrDirectContext* direct,
869
                                          sk_sp<SkColorSpace> target) const = 0;
870
871
    /** Creates SkImage in target SkColorSpace.
872
        Returns nullptr if SkImage could not be created.
873
874
        Returns original SkImage if it is in target SkColorSpace.
875
        Otherwise, converts pixels from SkImage SkColorSpace to target SkColorSpace.
876
        If SkImage colorSpace() returns nullptr, SkImage SkColorSpace is assumed to be sRGB.
877
878
        If this image is graphite-backed, the recorder parameter is required.
879
880
        @param targetColorSpace    SkColorSpace describing color range of returned SkImage
881
        @param recorder            The Recorder in which to create the new image
882
        @param RequiredProperties  properties the returned SkImage must possess (e.g. mipmaps)
883
        @return                    created SkImage in target SkColorSpace
884
    */
885
    virtual sk_sp<SkImage> makeColorSpace(skgpu::graphite::Recorder*,
886
                                          sk_sp<SkColorSpace> targetColorSpace,
887
                                          RequiredProperties) const = 0;
888
889
    /** Experimental.
890
        Creates SkImage in target SkColorType and SkColorSpace.
891
        Returns nullptr if SkImage could not be created.
892
893
        Returns original SkImage if it is in target SkColorType and SkColorSpace.
894
895
        If this image is texture-backed, the context parameter is required and must match the
896
        context of the source image.
897
898
        @param direct           The GrDirectContext in play, if it exists
899
        @param targetColorType  SkColorType of returned SkImage
900
        @param targetColorSpace SkColorSpace of returned SkImage
901
        @return                 created SkImage in target SkColorType and SkColorSpace
902
    */
903
    virtual sk_sp<SkImage> makeColorTypeAndColorSpace(GrDirectContext* direct,
904
                                                      SkColorType targetColorType,
905
                                                      sk_sp<SkColorSpace> targetCS) const = 0;
906
907
    /** Experimental.
908
        Creates SkImage in target SkColorType and SkColorSpace.
909
        Returns nullptr if SkImage could not be created.
910
911
        Returns original SkImage if it is in target SkColorType and SkColorSpace.
912
913
        If this image is graphite-backed, the recorder parameter is required.
914
915
        @param targetColorType     SkColorType of returned SkImage
916
        @param targetColorSpace    SkColorSpace of returned SkImage
917
        @param recorder            The Recorder in which to create the new image
918
        @param RequiredProperties  properties the returned SkImage must possess (e.g. mipmaps)
919
        @return                    created SkImage in target SkColorType and SkColorSpace
920
    */
921
    virtual sk_sp<SkImage> makeColorTypeAndColorSpace(skgpu::graphite::Recorder*,
922
                                                      SkColorType targetColorType,
923
                                                      sk_sp<SkColorSpace> targetColorSpace,
924
                                                      RequiredProperties) const = 0;
925
926
    /** Creates a new SkImage identical to this one, but with a different SkColorSpace.
927
        This does not convert the underlying pixel data, so the resulting image will draw
928
        differently.
929
    */
930
    sk_sp<SkImage> reinterpretColorSpace(sk_sp<SkColorSpace> newColorSpace) const;
931
932
private:
933
    SkImage(const SkImageInfo& info, uint32_t uniqueID);
934
935
    friend class SkBitmap;
936
    friend class SkImage_Base;   // for private ctor
937
    friend class SkImage_Raster; // for withMipmaps
938
    friend class SkMipmapBuilder;
939
940
    SkImageInfo     fInfo;
941
    const uint32_t  fUniqueID;
942
943
    sk_sp<SkImage> withMipmaps(sk_sp<SkMipmap>) const;
944
945
    using INHERITED = SkRefCnt;
946
};
947
948
#endif