/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkImage_DEFINED
#define SkImage_DEFINED

#include "include/core/SkFilterQuality.h"
#include "include/core/SkImageEncoder.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkTileMode.h"
#include "include/gpu/GrTypes.h"
#include <functional>  // std::function

#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
#include <android/hardware_buffer.h>
#endif

class SkData;
class SkCanvas;
class SkImageFilter;
class SkImageGenerator;
class SkPaint;
class SkPicture;
class SkSurface;
class GrBackendTexture;
class GrContext;
class GrContextThreadSafeProxy;
class GrTexture;

struct SkYUVAIndex;

/** \class SkImage
    SkImage describes a two dimensional array of pixels to draw. The pixels may be
    decoded in a raster bitmap, encoded in a SkPicture or compressed data stream,
    or located in GPU memory as a GPU texture.

    SkImage cannot be modified after it is created. SkImage may allocate additional
    storage as needed; for instance, an encoded SkImage may decode when drawn.

    SkImage width and height are greater than zero. Creating an SkImage with zero width
    or height returns SkImage equal to nullptr.

    SkImage may be created from SkBitmap, SkPixmap, SkSurface, SkPicture, encoded streams,
    GPU texture, YUV_ColorSpace data, or hardware buffer. Encoded streams supported
    include BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP. Supported encoding details
    vary with platform.
*/
class SK_API SkImage : public SkRefCnt {
public:

    /** Caller data passed to RasterReleaseProc; may be nullptr.
    */
    typedef void* ReleaseContext;

    /** Creates SkImage from SkPixmap and copy of pixels. Since pixels are copied, SkPixmap
        pixels may be modified or deleted without affecting SkImage.

        SkImage is returned if SkPixmap is valid. Valid SkPixmap parameters include:
        dimensions are greater than zero;
        each dimension fits in 29 bits;
        SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
        row bytes are large enough to hold one row of pixels;
        pixel address is not nullptr.

        @param pixmap  SkImageInfo, pixel address, and row bytes
        @return        copy of SkPixmap pixels, or nullptr

        example: https://fiddle.skia.org/c/@Image_MakeRasterCopy
    */
    static sk_sp<SkImage> MakeRasterCopy(const SkPixmap& pixmap);

    /** Creates SkImage from SkImageInfo, sharing pixels.

        SkImage is returned if SkImageInfo is valid. Valid SkImageInfo parameters include:
        dimensions are greater than zero;
        each dimension fits in 29 bits;
        SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
        rowBytes are large enough to hold one row of pixels;
        pixels is not nullptr, and contains enough data for SkImage.

        @param info      contains width, height, SkAlphaType, SkColorType, SkColorSpace
        @param pixels    address or pixel storage
        @param rowBytes  size of pixel row or larger
        @return          SkImage sharing pixels, or nullptr
    */
    static sk_sp<SkImage> MakeRasterData(const SkImageInfo& info, sk_sp<SkData> pixels,
                                         size_t rowBytes);

    /** Function called when SkImage no longer shares pixels. ReleaseContext is
        provided by caller when SkImage is created, and may be nullptr.
    */
    typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext);

    /** Creates SkImage from pixmap, sharing SkPixmap pixels. Pixels must remain valid and
        unchanged until rasterReleaseProc is called. rasterReleaseProc is passed
        releaseContext when SkImage is deleted or no longer refers to pixmap pixels.

        Pass nullptr for rasterReleaseProc to share SkPixmap without requiring a callback
        when SkImage is released. Pass nullptr for releaseContext if rasterReleaseProc
        does not require state.

        SkImage is returned if pixmap is valid. Valid SkPixmap parameters include:
        dimensions are greater than zero;
        each dimension fits in 29 bits;
        SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
        row bytes are large enough to hold one row of pixels;
        pixel address is not nullptr.

        @param pixmap             SkImageInfo, pixel address, and row bytes
        @param rasterReleaseProc  function called when pixels can be released; or nullptr
        @param releaseContext     state passed to rasterReleaseProc; or nullptr
        @return                   SkImage sharing pixmap
    */
    static sk_sp<SkImage> MakeFromRaster(const SkPixmap& pixmap,
                                         RasterReleaseProc rasterReleaseProc,
                                         ReleaseContext releaseContext);

    /** Creates SkImage from bitmap, sharing or copying bitmap pixels. If the bitmap
        is marked immutable, and its pixel memory is shareable, it may be shared
        instead of copied.

        SkImage is returned if bitmap is valid. Valid SkBitmap parameters include:
        dimensions are greater than zero;
        each dimension fits in 29 bits;
        SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
        row bytes are large enough to hold one row of pixels;
        pixel address is not nullptr.

        @param bitmap  SkImageInfo, row bytes, and pixels
        @return        created SkImage, or nullptr

        example: https://fiddle.skia.org/c/@Image_MakeFromBitmap
    */
    static sk_sp<SkImage> MakeFromBitmap(const SkBitmap& bitmap);

    /** Creates SkImage from data returned by imageGenerator. Generated data is owned by SkImage and
        may not be shared or accessed.

        subset allows selecting a portion of the full image. Pass nullptr to select the entire
        image; otherwise, subset must be contained by image bounds.

        SkImage is returned if generator data is valid. Valid data parameters vary by type of data
        and platform.

        imageGenerator may wrap SkPicture data, codec data, or custom data.

        @param imageGenerator  stock or custom routines to retrieve SkImage
        @param subset          bounds of returned SkImage; may be nullptr
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator,
                                            const SkIRect* subset = nullptr);

    /**
     *  Return an image backed by the encoded data, but attempt to defer decoding until the image
     *  is actually used/drawn. This deferral allows the system to cache the result, either on the
     *  CPU or on the GPU, depending on where the image is drawn. If memory is low, the cache may
     *  be purged, causing the next draw of the image to have to re-decode.
     *
     *  The subset parameter specifies a area within the decoded image to create the image from.
     *  If subset is null, then the entire image is returned.
     *
     *  This is similar to DecodeTo[Raster,Texture], but this method will attempt to defer the
     *  actual decode, while the DecodeTo... method explicitly decode and allocate the backend
     *  when the call is made.
     *
     *  If the encoded format is not supported, or subset is outside of the bounds of the decoded
     *  image, nullptr is returned.
     *
     *  @param encoded  the encoded data
     *  @param length   the number of bytes of encoded data
     *  @param subset   the bounds of the pixels within the decoded image to return. may be null.
     *  @return         created SkImage, or nullptr

        example: https://fiddle.skia.org/c/@Image_MakeFromEncoded
    */
    static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr);

    /**
     *  Decode the data in encoded/length into a raster image.
     *
     *  The subset parameter specifies a area within the decoded image to create the image from.
     *  If subset is null, then the entire image is returned.
     *
     *  This is similar to MakeFromEncoded, but this method will always decode immediately, and
     *  allocate the memory for the pixels for the lifetime of the returned image.
     *
     *  If the encoded format is not supported, or subset is outside of the bounds of the decoded
     *  image, nullptr is returned.
     *
     *  @param encoded  the encoded data
     *  @param length   the number of bytes of encoded data
     *  @param subset   the bounds of the pixels within the decoded image to return. may be null.
     *  @return         created SkImage, or nullptr
     */
    static sk_sp<SkImage> DecodeToRaster(const void* encoded, size_t length,
                                         const SkIRect* subset = nullptr);
    static sk_sp<SkImage> DecodeToRaster(const sk_sp<SkData>& data,
                                         const SkIRect* subset = nullptr) {
        return DecodeToRaster(data->data(), data->size(), subset);
    }

    /**
     *  Decode the data in encoded/length into a texture-backed image.
     *
     *  The subset parameter specifies a area within the decoded image to create the image from.
     *  If subset is null, then the entire image is returned.
     *
     *  This is similar to MakeFromEncoded, but this method will always decode immediately, and
     *  allocate the texture for the pixels for the lifetime of the returned image.
     *
     *  If the encoded format is not supported, or subset is outside of the bounds of the decoded
     *  image, nullptr is returned.
     *
     *  @param encoded  the encoded data
     *  @param length   the number of bytes of encoded data
     *  @param subset   the bounds of the pixels within the decoded image to return. may be null.
     *  @return         created SkImage, or nullptr
     */
    static sk_sp<SkImage> DecodeToTexture(GrContext* ctx, const void* encoded, size_t length,
                                          const SkIRect* subset = nullptr);
    static sk_sp<SkImage> DecodeToTexture(GrContext* ctx, const sk_sp<SkData>& data,
                                          const SkIRect* subset = nullptr) {
        return DecodeToTexture(ctx, data->data(), data->size(), subset);
    }

    // Experimental
    enum CompressionType {
        kETC1_CompressionType,
        kLast_CompressionType = kETC1_CompressionType,
    };

    /** Creates a GPU-backed SkImage from compressed data.

        SkImage is returned if format of the compressed data is supported.
        Supported formats vary by platform.

        @param context  GPU context
        @param data     compressed data to store in SkImage
        @param width    width of full SkImage
        @param height   height of full SkImage
        @param type     type of compression used
        @return         created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromCompressed(GrContext* context, sk_sp<SkData> data,
                                             int width, int height, CompressionType type);

    /** User function called when supplied texture may be deleted.
    */
    typedef void (*TextureReleaseProc)(ReleaseContext releaseContext);

    /** Creates SkImage from GPU texture associated with context. Caller is responsible for
        managing the lifetime of GPU texture.

        SkImage is returned if format of backendTexture is recognized and supported.
        Recognized formats vary by GPU back-end.

        @param context         GPU context
        @param backendTexture  texture residing on GPU
        @param origin          one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @param colorType       one of:
                               kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
                               kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
                               kRGB_888x_SkColorType, kBGRA_8888_SkColorType,
                               kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
                               kGray_8_SkColorType, kRGBA_F16_SkColorType
        @param alphaType       one of:
                               kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
                               kUnpremul_SkAlphaType
        @param colorSpace      range of colors; may be nullptr
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromTexture(GrContext* context,
                                          const GrBackendTexture& backendTexture,
                                          GrSurfaceOrigin origin,
                                          SkColorType colorType,
                                          SkAlphaType alphaType,
                                          sk_sp<SkColorSpace> colorSpace) {
        return MakeFromTexture(context, backendTexture, origin, colorType, alphaType, colorSpace,
                               nullptr, nullptr);
    }

    /** Creates SkImage from GPU texture associated with context. GPU texture must stay
        valid and unchanged until textureReleaseProc is called. textureReleaseProc is
        passed releaseContext when SkImage is deleted or no longer refers to texture.

        SkImage is returned if format of backendTexture is recognized and supported.
        Recognized formats vary by GPU back-end.

        @param context             GPU context
        @param backendTexture      texture residing on GPU
        @param origin              one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @param colorType           one of:
                                   kUnknown_SkColorType, kAlpha_8_SkColorType,
                                   kRGB_565_SkColorType, kARGB_4444_SkColorType,
                                   kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
                                   kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType,
                                   kRGB_101010x_SkColorType, kGray_8_SkColorType,
                                   kRGBA_F16_SkColorType
        @param alphaType           one of:
                                   kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
                                   kUnpremul_SkAlphaType
        @param colorSpace          range of colors; may be nullptr
        @param textureReleaseProc  function called when texture can be released
        @param releaseContext      state passed to textureReleaseProc
        @return                    created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromTexture(GrContext* context,
                                          const GrBackendTexture& backendTexture,
                                          GrSurfaceOrigin origin,
                                          SkColorType colorType,
                                          SkAlphaType alphaType,
                                          sk_sp<SkColorSpace> colorSpace,
                                          TextureReleaseProc textureReleaseProc,
                                          ReleaseContext releaseContext);

    /** Creates SkImage from pixmap. SkImage is uploaded to GPU back-end using context.

        Created SkImage is available to other GPU contexts, and is available across thread
        boundaries. All contexts must be in the same GPU share group, or otherwise
        share resources.

        When SkImage is no longer referenced, context releases texture memory
        asynchronously.

        GrBackendTexture created from pixmap is uploaded to match SkSurface created with
        dstColorSpace. SkColorSpace of SkImage is determined by pixmap.colorSpace().

        SkImage is returned referring to GPU back-end if context is not nullptr,
        format of data is recognized and supported, and if context supports moving
        resources between contexts. Otherwise, pixmap pixel data is copied and SkImage
        as returned in raster format if possible; nullptr may be returned.
        Recognized GPU formats vary by platform and GPU back-end.

        @param context                GPU context
        @param pixmap                 SkImageInfo, pixel address, and row bytes
        @param buildMips              create SkImage as mip map if true
        @param dstColorSpace          range of colors of matching SkSurface on GPU
        @param limitToMaxTextureSize  downscale image to GPU maximum texture size, if necessary
        @return                       created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeCrossContextFromPixmap(GrContext* context, const SkPixmap& pixmap,
                                                     bool buildMips,
                                                     bool limitToMaxTextureSize = false);

    /** Creates SkImage from backendTexture associated with context. backendTexture and
        returned SkImage are managed internally, and are released when no longer needed.

        SkImage is returned if format of backendTexture is recognized and supported.
        Recognized formats vary by GPU back-end.

        @param context         GPU context
        @param backendTexture  texture residing on GPU
        @param surfaceOrigin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @param colorType       one of:
                               kUnknown_SkColorType, kAlpha_8_SkColorType,
                               kRGB_565_SkColorType, kARGB_4444_SkColorType,
                               kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
                               kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType,
                               kRGB_101010x_SkColorType, kGray_8_SkColorType,
                               kRGBA_F16_SkColorType
        @param alphaType       one of:
                               kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
                               kUnpremul_SkAlphaType
        @param colorSpace      range of colors; may be nullptr
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext* context,
                                                 const GrBackendTexture& backendTexture,
                                                 GrSurfaceOrigin surfaceOrigin,
                                                 SkColorType colorType,
                                                 SkAlphaType alphaType = kPremul_SkAlphaType,
                                                 sk_sp<SkColorSpace> colorSpace = nullptr);

    /** Creates an SkImage by flattening the specified YUVA planes into a single, interleaved RGBA
        image.

        @param context         GPU context
        @param yuvColorSpace   How the YUV values are converted to RGB
        @param yuvaTextures    array of (up to four) YUVA textures on GPU which contain the,
                               possibly interleaved, YUVA planes
        @param yuvaIndices     array indicating which texture in yuvaTextures, and channel
                               in that texture, maps to each component of YUVA.
        @param imageSize       size of the resulting image
        @param imageOrigin     origin of the resulting image. One of: kBottomLeft_GrSurfaceOrigin,
                               kTopLeft_GrSurfaceOrigin
        @param imageColorSpace range of colors of the resulting image; may be nullptr
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromYUVATexturesCopy(GrContext* context,
                                                   SkYUVColorSpace yuvColorSpace,
                                                   const GrBackendTexture yuvaTextures[],
                                                   const SkYUVAIndex yuvaIndices[4],
                                                   SkISize imageSize,
                                                   GrSurfaceOrigin imageOrigin,
                                                   sk_sp<SkColorSpace> imageColorSpace = nullptr);

    /** Creates an SkImage by flattening the specified YUVA planes into a single, interleaved RGBA
        image. 'backendTexture' is used to store the result of the flattening.

        @param context            GPU context
        @param yuvColorSpace      How the YUV values are converted to RGB
        @param yuvaTextures       array of (up to four) YUVA textures on GPU which contain the,
                                  possibly interleaved, YUVA planes
        @param yuvaIndices        array indicating which texture in yuvaTextures, and channel
                                  in that texture, maps to each component of YUVA.
        @param imageSize          size of the resulting image
        @param imageOrigin        origin of the resulting image. One of:
                                            kBottomLeft_GrSurfaceOrigin,
                                            kTopLeft_GrSurfaceOrigin
        @param backendTexture     the resource that stores the final pixels
        @param imageColorSpace    range of colors of the resulting image; may be nullptr
        @param textureReleaseProc function called when backendTexture can be released
        @param releaseContext     state passed to textureReleaseProc
        @return                   created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromYUVATexturesCopyWithExternalBackend(
            GrContext* context,
            SkYUVColorSpace yuvColorSpace,
            const GrBackendTexture yuvaTextures[],
            const SkYUVAIndex yuvaIndices[4],
            SkISize imageSize,
            GrSurfaceOrigin imageOrigin,
            const GrBackendTexture& backendTexture,
            sk_sp<SkColorSpace> imageColorSpace = nullptr,
            TextureReleaseProc textureReleaseProc = nullptr,
            ReleaseContext releaseContext = nullptr);

    /** Creates an SkImage by storing the specified YUVA planes into an image, to be rendered
        via multitexturing.

        @param context         GPU context
        @param yuvColorSpace   How the YUV values are converted to RGB
        @param yuvaTextures    array of (up to four) YUVA textures on GPU which contain the,
                               possibly interleaved, YUVA planes
        @param yuvaIndices     array indicating which texture in yuvaTextures, and channel
                               in that texture, maps to each component of YUVA.
        @param imageSize       size of the resulting image
        @param imageOrigin     origin of the resulting image. One of: kBottomLeft_GrSurfaceOrigin,
                               kTopLeft_GrSurfaceOrigin
        @param imageColorSpace range of colors of the resulting image; may be nullptr
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromYUVATextures(GrContext* context,
                                               SkYUVColorSpace yuvColorSpace,
                                               const GrBackendTexture yuvaTextures[],
                                               const SkYUVAIndex yuvaIndices[4],
                                               SkISize imageSize,
                                               GrSurfaceOrigin imageOrigin,
                                               sk_sp<SkColorSpace> imageColorSpace = nullptr);

    /** Creates SkImage from pixmap array representing YUVA data.
        SkImage is uploaded to GPU back-end using context.

        Each GrBackendTexture created from yuvaPixmaps array is uploaded to match SkSurface
        using SkColorSpace of SkPixmap. SkColorSpace of SkImage is determined by imageColorSpace.

        SkImage is returned referring to GPU back-end if context is not nullptr and
        format of data is recognized and supported. Otherwise, nullptr is returned.
        Recognized GPU formats vary by platform and GPU back-end.

        @param context                GPU context
        @param yuvColorSpace          How the YUV values are converted to RGB
        @param yuvaPixmaps            array of (up to four) SkPixmap which contain the,
                                      possibly interleaved, YUVA planes
        @param yuvaIndices            array indicating which pixmap in yuvaPixmaps, and channel
                                      in that pixmap, maps to each component of YUVA.
        @param imageSize              size of the resulting image
        @param imageOrigin            origin of the resulting image. One of:
                                            kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @param buildMips              create internal YUVA textures as mip map if true
        @param limitToMaxTextureSize  downscale image to GPU maximum texture size, if necessary
        @param imageColorSpace        range of colors of the resulting image; may be nullptr
        @return                       created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromYUVAPixmaps(
            GrContext* context, SkYUVColorSpace yuvColorSpace, const SkPixmap yuvaPixmaps[],
            const SkYUVAIndex yuvaIndices[4], SkISize imageSize, GrSurfaceOrigin imageOrigin,
            bool buildMips, bool limitToMaxTextureSize = false,
            sk_sp<SkColorSpace> imageColorSpace = nullptr);

    /** To be deprecated.
    */
    static sk_sp<SkImage> MakeFromYUVTexturesCopy(GrContext* context, SkYUVColorSpace yuvColorSpace,
                                                  const GrBackendTexture yuvTextures[3],
                                                  GrSurfaceOrigin imageOrigin,
                                                  sk_sp<SkColorSpace> imageColorSpace = nullptr);

    /** To be deprecated.
    */
    static sk_sp<SkImage> MakeFromYUVTexturesCopyWithExternalBackend(
            GrContext* context,
            SkYUVColorSpace yuvColorSpace,
            const GrBackendTexture yuvTextures[3],
            GrSurfaceOrigin imageOrigin,
            const GrBackendTexture& backendTexture,
            sk_sp<SkColorSpace> imageColorSpace = nullptr);

    /** Creates SkImage from copy of nv12Textures, an array of textures on GPU.
        nv12Textures[0] contains pixels for YUV component y plane.
        nv12Textures[1] contains pixels for YUV component u plane,
        followed by pixels for YUV component v plane.
        Returned SkImage has the dimensions nv12Textures[2].
        yuvColorSpace describes how YUV colors convert to RGB colors.

        @param context         GPU context
        @param yuvColorSpace   How the YUV values are converted to RGB
        @param nv12Textures    array of YUV textures on GPU
        @param imageOrigin     one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @param imageColorSpace range of colors; may be nullptr
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromNV12TexturesCopy(GrContext* context,
                                                   SkYUVColorSpace yuvColorSpace,
                                                   const GrBackendTexture nv12Textures[2],
                                                   GrSurfaceOrigin imageOrigin,
                                                   sk_sp<SkColorSpace> imageColorSpace = nullptr);

    /** Creates SkImage from copy of nv12Textures, an array of textures on GPU.
        nv12Textures[0] contains pixels for YUV component y plane.
        nv12Textures[1] contains pixels for YUV component u plane,
        followed by pixels for YUV component v plane.
        Returned SkImage has the dimensions nv12Textures[2] and stores pixels in backendTexture.
        yuvColorSpace describes how YUV colors convert to RGB colors.

        @param context            GPU context
        @param yuvColorSpace   How the YUV values are converted to RGB
        @param nv12Textures       array of YUV textures on GPU
        @param imageOrigin        one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @param backendTexture     the resource that stores the final pixels
        @param imageColorSpace    range of colors; may be nullptr
        @param textureReleaseProc function called when backendTexture can be released
        @param releaseContext     state passed to textureReleaseProc
        @return                   created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromNV12TexturesCopyWithExternalBackend(
            GrContext* context,
            SkYUVColorSpace yuvColorSpace,
            const GrBackendTexture nv12Textures[2],
            GrSurfaceOrigin imageOrigin,
            const GrBackendTexture& backendTexture,
            sk_sp<SkColorSpace> imageColorSpace = nullptr,
            TextureReleaseProc textureReleaseProc = nullptr,
            ReleaseContext releaseContext = nullptr);

    enum class BitDepth {
        kU8,  //!< uses 8-bit unsigned int per color component
        kF16, //!< uses 16-bit float per color component
    };

    /** Creates SkImage from picture. Returned SkImage width and height are set by dimensions.
        SkImage draws picture with matrix and paint, set to bitDepth and colorSpace.

        If matrix is nullptr, draws with identity SkMatrix. If paint is nullptr, draws
        with default SkPaint. colorSpace may be nullptr.

        @param picture     stream of drawing commands
        @param dimensions  width and height
        @param matrix      SkMatrix to rotate, scale, translate, and so on; may be nullptr
        @param paint       SkPaint to apply transparency, filtering, and so on; may be nullptr
        @param bitDepth    8-bit integer or 16-bit float: per component
        @param colorSpace  range of colors; may be nullptr
        @return            created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture> picture, const SkISize& dimensions,
                                          const SkMatrix* matrix, const SkPaint* paint,
                                          BitDepth bitDepth,
                                          sk_sp<SkColorSpace> colorSpace);

#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
    /** (See Skia bug 7447)
        Creates SkImage from Android hardware buffer.
        Returned SkImage takes a reference on the buffer.

        Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.

        @param hardwareBuffer  AHardwareBuffer Android hardware buffer
        @param alphaType       one of:
                               kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
                               kUnpremul_SkAlphaType
        @param colorSpace      range of colors; may be nullptr
        @param surfaceOrigin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromAHardwareBuffer(
            AHardwareBuffer* hardwareBuffer,
            SkAlphaType alphaType = kPremul_SkAlphaType,
            sk_sp<SkColorSpace> colorSpace = nullptr,
            GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);

    /** Creates SkImage from Android hardware buffer and uploads the data from the SkPixmap to it.
        Returned SkImage takes a reference on the buffer.

        Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.

        @param pixmap          SkPixmap that contains data to be uploaded to the AHardwareBuffer
        @param hardwareBuffer  AHardwareBuffer Android hardware buffer
        @param surfaceOrigin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
        @return                created SkImage, or nullptr
    */
    static sk_sp<SkImage> MakeFromAHardwareBufferWithData(
            GrContext* context,
            const SkPixmap& pixmap,
            AHardwareBuffer* hardwareBuffer,
            GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
#endif

    /** Returns a SkImageInfo describing the width, height, color type, alpha type, and color space
        of the SkImage.

        @return  image info of SkImage.
    */
    const SkImageInfo& imageInfo() const { return fInfo; }

    /** Returns pixel count in each row.

        @return  pixel width in SkImage
    */
    int width() const { return fInfo.width(); }

    /** Returns pixel row count.

        @return  pixel height in SkImage
    */
    int height() const { return fInfo.height(); }

    /** Returns SkISize { width(), height() }.

        @return  integral size of width() and height()
    */
    SkISize dimensions() const { return SkISize::Make(fInfo.width(), fInfo.height()); }

    /** Returns SkIRect { 0, 0, width(), height() }.

        @return  integral rectangle from origin to width() and height()
    */
    SkIRect bounds() const { return SkIRect::MakeWH(fInfo.width(), fInfo.height()); }

    /** Returns value unique to image. SkImage contents cannot change after SkImage is
        created. Any operation to create a new SkImage will receive generate a new
        unique number.

        @return  unique identifier
    */
    uint32_t uniqueID() const { return fUniqueID; }

    /** Returns SkAlphaType, one of:
        kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
        kUnpremul_SkAlphaType.

        SkAlphaType returned was a parameter to an SkImage constructor,
        or was parsed from encoded data.

        @return  SkAlphaType in SkImage

        example: https://fiddle.skia.org/c/@Image_alphaType
    */
    SkAlphaType alphaType() const;

    /** Returns SkColorType if known; otherwise, returns kUnknown_SkColorType.

        @return  SkColorType of SkImage

        example: https://fiddle.skia.org/c/@Image_colorType
    */
    SkColorType colorType() const;

    /** Returns SkColorSpace, the range of colors, associated with SkImage.  The
        reference count of SkColorSpace is unchanged. The returned SkColorSpace is
        immutable.

        SkColorSpace returned was passed to an SkImage constructor,
        or was parsed from encoded data. SkColorSpace returned may be ignored when SkImage
        is drawn, depending on the capabilities of the SkSurface receiving the drawing.

        @return  SkColorSpace in SkImage, or nullptr

        example: https://fiddle.skia.org/c/@Image_colorSpace
    */
    SkColorSpace* colorSpace() const;

    /** Returns a smart pointer to SkColorSpace, the range of colors, associated with
        SkImage.  The smart pointer tracks the number of objects sharing this
        SkColorSpace reference so the memory is released when the owners destruct.

        The returned SkColorSpace is immutable.

        SkColorSpace returned was passed to an SkImage constructor,
        or was parsed from encoded data. SkColorSpace returned may be ignored when SkImage
        is drawn, depending on the capabilities of the SkSurface receiving the drawing.

        @return  SkColorSpace in SkImage, or nullptr, wrapped in a smart pointer

        example: https://fiddle.skia.org/c/@Image_refColorSpace
    */
    sk_sp<SkColorSpace> refColorSpace() const;

    /** Returns true if SkImage pixels represent transparency only. If true, each pixel
        is packed in 8 bits as defined by kAlpha_8_SkColorType.

        @return  true if pixels represent a transparency mask

        example: https://fiddle.skia.org/c/@Image_isAlphaOnly
    */
    bool isAlphaOnly() const;

    /** Returns true if pixels ignore their alpha value and are treated as fully opaque.

        @return  true if SkAlphaType is kOpaque_SkAlphaType
    */
    bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }

    /** Creates SkShader from SkImage. SkShader dimensions are taken from SkImage. SkShader uses
        SkTileMode rules to fill drawn area outside SkImage. localMatrix permits
        transforming SkImage before SkCanvas matrix is applied.

        @param tmx          tiling in the x direction
        @param tmy          tiling in the y direction
        @param localMatrix  SkImage transformation, or nullptr
        @return             SkShader containing SkImage
    */
    sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
                               const SkMatrix* localMatrix = nullptr) const;
    sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, const SkMatrix& localMatrix) const {
        return this->makeShader(tmx, tmy, &localMatrix);
    }

    /** Creates SkShader from SkImage. SkShader dimensions are taken from SkImage. SkShader uses
        SkShader::kClamp_TileMode to fill drawn area outside SkImage. localMatrix permits
        transforming SkImage before SkCanvas matrix is applied.

        @param localMatrix  SkImage transformation, or nullptr
        @return             SkShader containing SkImage
    */
    sk_sp<SkShader> makeShader(const SkMatrix* localMatrix = nullptr) const {
        return this->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, localMatrix);
    }
    sk_sp<SkShader> makeShader(const SkMatrix& localMatrix) const {
        return this->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, &localMatrix);
    }


    /** Copies SkImage pixel address, row bytes, and SkImageInfo to pixmap, if address
        is available, and returns true. If pixel address is not available, return
        false and leave pixmap unchanged.

        @param pixmap  storage for pixel state if pixels are readable; otherwise, ignored
        @return        true if SkImage has direct access to pixels

        example: https://fiddle.skia.org/c/@Image_peekPixels
    */
    bool peekPixels(SkPixmap* pixmap) const;

    /** Deprecated.
    */
    GrTexture* getTexture() const;

    /** Returns true the contents of SkImage was created on or uploaded to GPU memory,
        and is available as a GPU texture.

        @return  true if SkImage is a GPU texture

        example: https://fiddle.skia.org/c/@Image_isTextureBacked
    */
    bool isTextureBacked() const;

    /** Returns true if SkImage can be drawn on either raster surface or GPU surface.
        If context is nullptr, tests if SkImage draws on raster surface;
        otherwise, tests if SkImage draws on GPU surface associated with context.

        SkImage backed by GPU texture may become invalid if associated GrContext is
        invalid. lazy image may be invalid and may not draw to raster surface or
        GPU surface or both.

        @param context  GPU context
        @return         true if SkImage can be drawn

        example: https://fiddle.skia.org/c/@Image_isValid
    */
    bool isValid(GrContext* context) const;

    /** Flushes any pending uses of texture-backed images in the GPU backend. If the image is not
        texture-backed (including promise texture images) or if the the GrContext does not
        have the same context ID as the context backing the image then this is a no-op.

        If the image was not used in any non-culled draws recorded on the passed GrContext then
        this is a no-op unless the GrFlushInfo contains semaphores, a finish proc, or uses
        kSyncCpu_GrFlushFlag. Those are respected even when the image has not been used.

        @param context  the context on which to flush pending usages of the image.
        @param info     flush options
        @return         one of: GrSemaphoresSubmitted::kYes, GrSemaphoresSubmitted::kNo
     */
    GrSemaphoresSubmitted flush(GrContext* context, const GrFlushInfo& flushInfo);

    /** Version of flush() that uses a default GrFlushInfo. */
    void flush(GrContext*);

    /** Retrieves the back-end texture. If SkImage has no back-end texture, an invalid
        object is returned. Call GrBackendTexture::isValid to determine if the result
        is valid.

        If flushPendingGrContextIO is true, completes deferred I/O operations.

        If origin in not nullptr, copies location of content drawn into SkImage.

        @param flushPendingGrContextIO  flag to flush outstanding requests
        @param origin                   storage for one of: kTopLeft_GrSurfaceOrigin,
                                        kBottomLeft_GrSurfaceOrigin; or nullptr
        @return                         back-end API texture handle; invalid on failure
    */
    GrBackendTexture getBackendTexture(bool flushPendingGrContextIO,
                                       GrSurfaceOrigin* origin = nullptr) const;

    /** \enum SkImage::CachingHint
        CachingHint selects whether Skia may internally cache SkBitmap generated by
        decoding SkImage, or by copying SkImage from GPU to CPU. The default behavior
        allows caching SkBitmap.

        Choose kDisallow_CachingHint if SkImage pixels are to be used only once, or
        if SkImage pixels reside in a cache outside of Skia, or to reduce memory pressure.

        Choosing kAllow_CachingHint does not ensure that pixels will be cached.
        SkImage pixels may not be cached if memory requirements are too large or
        pixels are not accessible.
    */
    enum CachingHint {
        kAllow_CachingHint,    //!< allows internally caching decoded and copied pixels
        kDisallow_CachingHint, //!< disallows internally caching decoded and copied pixels
    };

    /** Copies SkRect of pixels from SkImage to dstPixels. Copy starts at offset (srcX, srcY),
        and does not exceed SkImage (width(), height()).

        dstInfo specifies width, height, SkColorType, SkAlphaType, and SkColorSpace of
        destination. dstRowBytes specifies the gap from one destination row to the next.
        Returns true if pixels are copied. Returns false if:
        - dstInfo.addr() equals nullptr
        - dstRowBytes is less than dstInfo.minRowBytes()
        - SkPixelRef is nullptr

        Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
        kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
        If SkImage SkColorType is kGray_8_SkColorType, dstInfo.colorSpace() must match.
        If SkImage SkAlphaType is kOpaque_SkAlphaType, dstInfo.alphaType() must
        match. If SkImage SkColorSpace is nullptr, dstInfo.colorSpace() must match. Returns
        false if pixel conversion is not possible.

        srcX and srcY may be negative to copy only top or left of source. Returns
        false if width() or height() is zero or negative.
        Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().

        If cachingHint is kAllow_CachingHint, pixels may be retained locally.
        If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.

        @param dstInfo      destination width, height, SkColorType, SkAlphaType, SkColorSpace
        @param dstPixels    destination pixel storage
        @param dstRowBytes  destination row length
        @param srcX         column index whose absolute value is less than width()
        @param srcY         row index whose absolute value is less than height()
        @param cachingHint  one of: kAllow_CachingHint, kDisallow_CachingHint
        @return             true if pixels are copied to dstPixels
    */
    bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
                    int srcX, int srcY, CachingHint cachingHint = kAllow_CachingHint) const;

    /** Copies a SkRect of pixels from SkImage to dst. Copy starts at (srcX, srcY), and
        does not exceed SkImage (width(), height()).

        dst specifies width, height, SkColorType, SkAlphaType, SkColorSpace, pixel storage,
        and row bytes of destination. dst.rowBytes() specifics the gap from one destination
        row to the next. Returns true if pixels are copied. Returns false if:
        - dst pixel storage equals nullptr
        - dst.rowBytes is less than SkImageInfo::minRowBytes
        - SkPixelRef is nullptr

        Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
        kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
        If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
        If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
        match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
        false if pixel conversion is not possible.

        srcX and srcY may be negative to copy only top or left of source. Returns
        false if width() or height() is zero or negative.
        Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().

        If cachingHint is kAllow_CachingHint, pixels may be retained locally.
        If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.

        @param dst          destination SkPixmap: SkImageInfo, pixels, row bytes
        @param srcX         column index whose absolute value is less than width()
        @param srcY         row index whose absolute value is less than height()
        @param cachingHint  one of: kAllow_CachingHint, kDisallow_CachingHint
        @return             true if pixels are copied to dst
    */
    bool readPixels(const SkPixmap& dst, int srcX, int srcY,
                    CachingHint cachingHint = kAllow_CachingHint) const;

    /** Copies SkImage to dst, scaling pixels to fit dst.width() and dst.height(), and
        converting pixels to match dst.colorType() and dst.alphaType(). Returns true if
        pixels are copied. Returns false if dst.addr() is nullptr, or dst.rowBytes() is
        less than dst SkImageInfo::minRowBytes.

        Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
        kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
        If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
        If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
        match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
        false if pixel conversion is not possible.

        Scales the image, with filterQuality, to match dst.width() and dst.height().
        filterQuality kNone_SkFilterQuality is fastest, typically implemented with
        nearest neighbor filter. kLow_SkFilterQuality is typically implemented with
        bilerp filter. kMedium_SkFilterQuality is typically implemented with
        bilerp filter, and mip-map filter when size is reduced.
        kHigh_SkFilterQuality is slowest, typically implemented with bicubic filter.

        If cachingHint is kAllow_CachingHint, pixels may be retained locally.
        If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.

        @param dst            destination SkPixmap: SkImageInfo, pixels, row bytes
        @param filterQuality  one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
                              kMedium_SkFilterQuality, kHigh_SkFilterQuality
        @param cachingHint    one of: kAllow_CachingHint, kDisallow_CachingHint
        @return               true if pixels are scaled to fit dst
    */
    bool scalePixels(const SkPixmap& dst, SkFilterQuality filterQuality,
                     CachingHint cachingHint = kAllow_CachingHint) const;

    /** Encodes SkImage pixels, returning result as SkData.

        Returns nullptr if encoding fails, or if encodedImageFormat is not supported.

        SkImage encoding in a format requires both building with one or more of:
        SK_HAS_JPEG_LIBRARY, SK_HAS_PNG_LIBRARY, SK_HAS_WEBP_LIBRARY; and platform support
        for the encoded format.

        If SK_BUILD_FOR_MAC or SK_BUILD_FOR_IOS is defined, encodedImageFormat can
        additionally be one of: SkEncodedImageFormat::kICO, SkEncodedImageFormat::kBMP,
        SkEncodedImageFormat::kGIF.

        quality is a platform and format specific metric trading off size and encoding
        error. When used, quality equaling 100 encodes with the least error. quality may
        be ignored by the encoder.

        @param encodedImageFormat  one of: SkEncodedImageFormat::kJPEG, SkEncodedImageFormat::kPNG,
                                   SkEncodedImageFormat::kWEBP
        @param quality             encoder specific metric with 100 equaling best
        @return                    encoded SkImage, or nullptr

        example: https://fiddle.skia.org/c/@Image_encodeToData
    */
    sk_sp<SkData> encodeToData(SkEncodedImageFormat encodedImageFormat, int quality) const;

    /** Encodes SkImage pixels, returning result as SkData. Returns existing encoded data
        if present; otherwise, SkImage is encoded with SkEncodedImageFormat::kPNG. Skia
        must be built with SK_HAS_PNG_LIBRARY to encode SkImage.

        Returns nullptr if existing encoded data is missing or invalid, and
        encoding fails.

        @return  encoded SkImage, or nullptr

        example: https://fiddle.skia.org/c/@Image_encodeToData_2
    */
    sk_sp<SkData> encodeToData() const;

    /** Returns encoded SkImage pixels as SkData, if SkImage was created from supported
        encoded stream format. Platform support for formats vary and may require building
        with one or more of: SK_HAS_JPEG_LIBRARY, SK_HAS_PNG_LIBRARY, SK_HAS_WEBP_LIBRARY.

        Returns nullptr if SkImage contents are not encoded.

        @return  encoded SkImage, or nullptr

        example: https://fiddle.skia.org/c/@Image_refEncodedData
    */
    sk_sp<SkData> refEncodedData() const;

    /** Returns subset of SkImage. subset must be fully contained by SkImage dimensions().
        The implementation may share pixels, or may copy them.

        Returns nullptr if subset is empty, or subset is not contained by bounds, or
        pixels in SkImage could not be read or copied.

        @param subset  bounds of returned SkImage
        @return        partial or full SkImage, or nullptr

        example: https://fiddle.skia.org/c/@Image_makeSubset
    */
    sk_sp<SkImage> makeSubset(const SkIRect& subset) const;

    /** Returns SkImage backed by GPU texture associated with context. Returned SkImage is
        compatible with SkSurface created with dstColorSpace. The returned SkImage respects
        mipMapped setting; if mipMapped equals GrMipMapped::kYes, the backing texture
        allocates mip map levels. Returns original SkImage if context
        and dstColorSpace match and mipMapped is compatible with backing GPU texture.

        Returns nullptr if context is nullptr, or if SkImage was created with another
        GrContext.

        @param context        GPU context
        @param dstColorSpace  range of colors of matching SkSurface on GPU
        @param mipMapped      whether created SkImage texture must allocate mip map levels
        @return               created SkImage, or nullptr
    */
    sk_sp<SkImage> makeTextureImage(GrContext* context, GrMipMapped = GrMipMapped::kNo) const;

    /** Returns raster image or lazy image. Copies SkImage backed by GPU texture into
        CPU memory if needed. Returns original SkImage if decoded in raster bitmap,
        or if encoded in a stream.

        Returns nullptr if backed by GPU texture and copy fails.

        @return  raster image, lazy image, or nullptr

        example: https://fiddle.skia.org/c/@Image_makeNonTextureImage
    */
    sk_sp<SkImage> makeNonTextureImage() const;

    /** Returns raster image. Copies SkImage backed by GPU texture into CPU memory,
        or decodes SkImage from lazy image. Returns original SkImage if decoded in
        raster bitmap.

        Returns nullptr if copy, decode, or pixel read fails.

        @return  raster image, or nullptr

        example: https://fiddle.skia.org/c/@Image_makeRasterImage
    */
    sk_sp<SkImage> makeRasterImage() const;

    /** Creates filtered SkImage. filter processes original SkImage, potentially changing
        color, position, and size. subset is the bounds of original SkImage processed
        by filter. clipBounds is the expected bounds of the filtered SkImage. outSubset
        is required storage for the actual bounds of the filtered SkImage. offset is
        required storage for translation of returned SkImage.

        Returns nullptr if SkImage could not be created. If nullptr is returned, outSubset
        and offset are undefined.

        Useful for animation of SkImageFilter that varies size from frame to frame.
        Returned SkImage is created larger than required by filter so that GPU texture
        can be reused with different sized effects. outSubset describes the valid bounds
        of GPU texture returned. offset translates the returned SkImage to keep subsequent
        animation frames aligned with respect to each other.

        @param context     the GrContext in play - if it exists
        @param filter      how SkImage is sampled when transformed
        @param subset      bounds of SkImage processed by filter
        @param clipBounds  expected bounds of filtered SkImage
        @param outSubset   storage for returned SkImage bounds
        @param offset      storage for returned SkImage translation
        @return            filtered SkImage, or nullptr
    */
    sk_sp<SkImage> makeWithFilter(GrContext* context,
                                  const SkImageFilter* filter, const SkIRect& subset,
                                  const SkIRect& clipBounds, SkIRect* outSubset,
                                  SkIPoint* offset) const;

    /** To be deprecated.
    */
    sk_sp<SkImage> makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
                                  const SkIRect& clipBounds, SkIRect* outSubset,
                                  SkIPoint* offset) const;

    /** Defines a callback function, taking one parameter of type GrBackendTexture with
        no return value. Function is called when back-end texture is to be released.
    */
    typedef std::function<void(GrBackendTexture)> BackendTextureReleaseProc;

    /** Creates a GrBackendTexture from the provided SkImage. Returns true and
        stores result in backendTexture and backendTextureReleaseProc if
        texture is created; otherwise, returns false and leaves
        backendTexture and backendTextureReleaseProc unmodified.

        Call backendTextureReleaseProc after deleting backendTexture.
        backendTextureReleaseProc cleans up auxiliary data related to returned
        backendTexture. The caller must delete returned backendTexture after use.

        If SkImage is both texture backed and singly referenced, image is returned in
        backendTexture without conversion or making a copy. SkImage is singly referenced
        if its was transferred solely using std::move().

        If SkImage is not texture backed, returns texture with SkImage contents.

        @param context                    GPU context
        @param image                      SkImage used for texture
        @param backendTexture             storage for back-end texture
        @param backendTextureReleaseProc  storage for clean up function
        @return                           true if back-end texture was created
    */
    static bool MakeBackendTextureFromSkImage(GrContext* context,
                                              sk_sp<SkImage> image,
                                              GrBackendTexture* backendTexture,
                                              BackendTextureReleaseProc* backendTextureReleaseProc);

    /** Deprecated.
     */
    enum LegacyBitmapMode {
        kRO_LegacyBitmapMode, //!< returned bitmap is read-only and immutable
    };

    /** Deprecated.
        Creates raster SkBitmap with same pixels as SkImage. If legacyBitmapMode is
        kRO_LegacyBitmapMode, returned bitmap is read-only and immutable.
        Returns true if SkBitmap is stored in bitmap. Returns false and resets bitmap if
        SkBitmap write did not succeed.

        @param bitmap            storage for legacy SkBitmap
        @param legacyBitmapMode  bitmap is read-only and immutable
        @return                  true if SkBitmap was created
    */
    bool asLegacyBitmap(SkBitmap* bitmap,
                        LegacyBitmapMode legacyBitmapMode = kRO_LegacyBitmapMode) const;

    /** Returns true if SkImage is backed by an image-generator or other service that creates
        and caches its pixels or texture on-demand.

        @return  true if SkImage is created as needed

        example: https://fiddle.skia.org/c/@Image_isLazyGenerated_a
        example: https://fiddle.skia.org/c/@Image_isLazyGenerated_b
    */
    bool isLazyGenerated() const;

    /** Creates SkImage in target SkColorSpace.
        Returns nullptr if SkImage could not be created.

        Returns original SkImage if it is in target SkColorSpace.
        Otherwise, converts pixels from SkImage SkColorSpace to target SkColorSpace.
        If SkImage colorSpace() returns nullptr, SkImage SkColorSpace is assumed to be sRGB.

        @param target  SkColorSpace describing color range of returned SkImage
        @return        created SkImage in target SkColorSpace

        example: https://fiddle.skia.org/c/@Image_makeColorSpace
    */
    sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target) const;

    /** Experimental.
        Creates SkImage in target SkColorType and SkColorSpace.
        Returns nullptr if SkImage could not be created.

        Returns original SkImage if it is in target SkColorType and SkColorSpace.

        @param targetColorType  SkColorType of returned SkImage
        @param targetColorSpace SkColorSpace of returned SkImage
        @return                 created SkImage in target SkColorType and SkColorSpace
    */
    sk_sp<SkImage> makeColorTypeAndColorSpace(SkColorType targetColorType,
                                              sk_sp<SkColorSpace> targetColorSpace) const;

    /** Creates a new SkImage identical to this one, but with a different SkColorSpace.
        This does not convert the underlying pixel data, so the resulting image will draw
        differently.
    */
    sk_sp<SkImage> reinterpretColorSpace(sk_sp<SkColorSpace> newColorSpace) const;

private:
    SkImage(const SkImageInfo& info, uint32_t uniqueID);
    friend class SkImage_Base;

    SkImageInfo     fInfo;
    const uint32_t  fUniqueID;

    typedef SkRefCnt INHERITED;
};

#endif
