/*
 * 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 "SkFilterQuality.h"
#include "SkImageInfo.h"
#include "SkImageEncoder.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkShader.h"

class SkData;
class SkCanvas;
class SkColorTable;
class SkCrossContextImageData;
class SkImageGenerator;
class SkPaint;
class SkPicture;
class SkPixelSerializer;
class SkString;
class SkSurface;
class GrBackendTexture;
class GrContext;
class GrContextThreadSafeProxy;
class GrTexture;

/**
 *  SkImage is an abstraction for drawing a rectagle of pixels, though the
 *  particular type of image could be actually storing its data on the GPU, or
 *  as drawing commands (picture or PDF or otherwise), ready to be played back
 *  into another canvas.
 *
 *  The content of SkImage is always immutable, though the actual storage may
 *  change, if for example that image can be re-created via encoded data or
 *  other means.
 *
 *  SkImage always has a non-zero dimensions. If there is a request to create a new image, either
 *  directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be
 *  returned.
 */
class SK_API SkImage : public SkRefCnt {
public:
    typedef SkImageInfo Info;
    typedef void* ReleaseContext;

    static sk_sp<SkImage> MakeRasterCopy(const SkPixmap&);
    static sk_sp<SkImage> MakeRasterData(const Info&, sk_sp<SkData> pixels, size_t rowBytes);

    typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext);

    /**
     *  Return a new Image referencing the specified pixels. These must remain valid and unchanged
     *  until the specified release-proc is called, indicating that Skia no longer has a reference
     *  to the pixels.
     *
     *  Returns NULL if the requested pixmap info is unsupported.
     */
    static sk_sp<SkImage> MakeFromRaster(const SkPixmap&, RasterReleaseProc, ReleaseContext);

    /**
     *  Construct a new image from the specified bitmap. If the bitmap is marked immutable, and
     *  its pixel memory is shareable, it may be shared instead of copied.
     */
    static sk_sp<SkImage> MakeFromBitmap(const SkBitmap&);

    /**
     *  Construct a new SkImage based on the given ImageGenerator. Returns NULL on error.
     *  This function will always take ownership of the passed generator.
     *
     *  If a subset is specified, it must be contained within the generator's bounds.
     */
    static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator>,
                                            const SkIRect* subset = nullptr);

    /**
     *  Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
     *  which can mean that the format of the encoded data was not recognized/supported.
     *
     *  If a subset is specified, it must be contained within the encoded data's bounds.
     */
    static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr);

    /**
     *  Create a new image from the specified descriptor. Note - the caller is responsible for
     *  managing the lifetime of the underlying platform texture.
     *
     *  Will return NULL if the specified descriptor is unsupported.
     *
     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
     *  GrBackendTextureDesc. This method will eventually be removed.
     */
    static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
        return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr, nullptr);
    }

    static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& de,
                                          SkAlphaType at) {
        return MakeFromTexture(ctx, de, at, nullptr, nullptr, nullptr);
    }

    typedef void (*TextureReleaseProc)(ReleaseContext);

    /**
     *  Create a new image from the specified descriptor. The underlying platform texture must stay
     *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
     *  no longer is holding a reference to it.
     *
     *  Will return NULL if the specified descriptor is unsupported.
     *
     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
     *  GrBackendTextureDesc. This method will eventually be removed.
     */
    static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
                                          SkAlphaType at, TextureReleaseProc trp,
                                          ReleaseContext rc) {
        return MakeFromTexture(ctx, desc, at, nullptr, trp, rc);
    }

    /**
    *  Create a new image from the specified descriptor. The underlying platform texture must stay
    *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
    *  no longer is holding a reference to it.
    *
    *  Will return NULL if the specified descriptor is unsupported.
     *
     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
     *  GrBackendTextureDesc. This method will eventually be removed.
    */
    static sk_sp<SkImage> MakeFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
                                          sk_sp<SkColorSpace>, TextureReleaseProc, ReleaseContext);

    /**
     *  Create a new image from the specified descriptor. Note - the caller is responsible for
     *  managing the lifetime of the underlying platform texture.
     *
     *  Will return NULL if the specified backend texture is unsupported.
     */
    static sk_sp<SkImage> MakeFromTexture(GrContext* ctx,
                                          const GrBackendTexture& tex, GrSurfaceOrigin origin,
                                          SkAlphaType at, sk_sp<SkColorSpace> cs) {
        return MakeFromTexture(ctx, tex, origin, at, cs, nullptr, nullptr);
    }

    /**
     *  Create a new image from the GrBackendTexture. The underlying platform texture must stay
     *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
     *  no longer is holding a reference to it.
     *
     *  Will return NULL if the specified backend texture is unsupported.
     */
    static sk_sp<SkImage> MakeFromTexture(GrContext*,
                                          const GrBackendTexture&, GrSurfaceOrigin origin,
                                          SkAlphaType, sk_sp<SkColorSpace>,
                                          TextureReleaseProc, ReleaseContext);


    /**
     *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
     *  texture when the image is released.
     *
     *  Will return NULL if the specified descriptor is unsupported.
     *
     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
     *  GrBackendTextureDesc. This method will eventually be removed.
     */
    static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
                                                 SkAlphaType = kPremul_SkAlphaType,
                                                 sk_sp<SkColorSpace> = nullptr);

    /**
     *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
     *  texture when the image is released.
     *
     *  Will return NULL if the specified backend texture is unsupported.
     */
    static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*,
                                                 const GrBackendTexture&, GrSurfaceOrigin,
                                                 SkAlphaType = kPremul_SkAlphaType,
                                                 sk_sp<SkColorSpace> = nullptr);

    /**
     *  Create a new image by copying the pixels from the specified y, u, v textures. The data
     *  from the textures is immediately ingested into the image and the textures can be modified or
     *  deleted after the function returns. The image will have the dimensions of the y texture.
     */
    static sk_sp<SkImage> MakeFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
                                                  const GrBackendObject yuvTextureHandles[3],
                                                  const SkISize yuvSizes[3],
                                                  GrSurfaceOrigin,
                                                  sk_sp<SkColorSpace> = nullptr);

    /**
     *  Create a new image by copying the pixels from the specified y and uv textures. The data
     *  from the textures is immediately ingested into the image and the textures can be modified or
     *  deleted after the function returns. The image will have the dimensions of the y texture.
     */
    static sk_sp<SkImage> MakeFromNV12TexturesCopy(GrContext*, SkYUVColorSpace,
                                                   const GrBackendObject nv12TextureHandles[2],
                                                   const SkISize nv12Sizes[2], GrSurfaceOrigin,
                                                   sk_sp<SkColorSpace> = nullptr);

    enum class BitDepth {
        kU8,
        kF16,
    };

    /**
     *  Create a new image from the specified picture.
     *  On creation of the SkImage, snap the SkPicture to a particular BitDepth and SkColorSpace.
     */
    static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture>, const SkISize& dimensions,
                                          const SkMatrix*, const SkPaint*, BitDepth,
                                          sk_sp<SkColorSpace>);

    ///////////////////////////////////////////////////////////////////////////////////////////////

    int width() const { return fWidth; }
    int height() const { return fHeight; }
    SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
    SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
    uint32_t uniqueID() const { return fUniqueID; }
    SkAlphaType alphaType() const;

    /**
     *  Returns the color space of the SkImage.
     *
     *  This is the color space that was supplied on creation of the SkImage or a color
     *  space that was parsed from encoded data.  This color space is not guaranteed to be
     *  renderable.  Can return nullptr if the SkImage was created without a color space.
     */
    SkColorSpace* colorSpace() const;
    sk_sp<SkColorSpace> refColorSpace() const;

    /**
     *  Returns true fi the image will be drawn as a mask, with no intrinsic color of its own.
     */
    bool isAlphaOnly() const;
    bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }

    /**
     * Extracts YUV planes from the SkImage and stores them in client-provided memory. The sizes
     * planes and rowBytes arrays are ordered [y, u, v].
     */
    bool readYUV8Planes(const SkISize[3], void* const planes[3], const size_t rowBytes[3],
                        SkYUVColorSpace) const;

    sk_sp<SkShader> makeShader(SkShader::TileMode, SkShader::TileMode,
                               const SkMatrix* localMatrix = nullptr) const;

    /**
     *  If the image has direct access to its pixels (i.e. they are in local RAM)
     *  return true, and if not null, return in the pixmap parameter the info about the
     *  images pixels.
     *
     *  On failure, return false and ignore the pixmap parameter.
     */
    bool peekPixels(SkPixmap* pixmap) const;

    // DEPRECATED - currently used by Canvas2DLayerBridge in Chromium.
    GrTexture* getTexture() const;

    /**
     *  Returns true if the image is texture backed.
     */
    bool isTextureBacked() const;

    /**
     *  Retrieves the backend API handle of the texture. If flushPendingGrContextIO then the
     *  GrContext will issue to the backend API any deferred IO operations on the texture before
     *  returning.
     *  If 'origin' is supplied it will be filled in with the origin of the content drawn
     *  into the image.
     */
    GrBackendObject getTextureHandle(bool flushPendingGrContextIO,
                                     GrSurfaceOrigin* origin = nullptr) const;

    /**
     *  Hints to image calls where the system might cache computed intermediates (e.g. the results
     *  of decoding or a read-back from the GPU. Passing kAllow signals that the system's default
     *  behavior is fine. Passing kDisallow signals that caching should be avoided.
     */
     enum CachingHint {
        kAllow_CachingHint,
        kDisallow_CachingHint,
    };

    /**
     *  Copy the pixels from the image into the specified buffer (pixels + rowBytes),
     *  converting them into the requested format (dstInfo). The image pixels are read
     *  starting at the specified (srcX,srcY) location.
     *
     *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
     *
     *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
     *
     *  srcR is intersected with the bounds of the image. If this intersection is not empty,
     *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
     *  corresponding src pixels, performing any colortype/alphatype transformations needed
     *  (in the case where the src and dst have different colortypes or alphatypes).
     *
     *  This call can fail, returning false, for several reasons:
     *  - If srcR does not intersect the image bounds.
     *  - If the requested colortype/alphatype cannot be converted from the image's types.
     */
    bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
                    int srcX, int srcY, CachingHint = kAllow_CachingHint) const;

    bool readPixels(const SkPixmap& dst, int srcX, int srcY,
                    CachingHint = kAllow_CachingHint) const;

    /**
     *  Copy the pixels from this image into the dst pixmap, converting as needed into dst's
     *  colortype/alphatype. If the conversion cannot be performed, false is returned.
     *
     *  If dst's dimensions differ from the src dimension, the image will be scaled, applying the
     *  specified filter-quality.
     */
    bool scalePixels(const SkPixmap& dst, SkFilterQuality, CachingHint = kAllow_CachingHint) const;

    /**
     *  Encode the image's pixels and return the result as a new SkData, which
     *  the caller must manage (i.e. call unref() when they are done).
     *
     *  If the image type cannot be encoded, or the requested encoder type is
     *  not supported, this will return NULL.
     *
     *  Note: this will attempt to encode the image's pixels in the specified format,
     *  even if the image returns a data from refEncoded(). That data will be ignored.
     */
    SkData* encode(SkEncodedImageFormat, int quality) const;

    /**
     *  Encode the image and return the result as a caller-managed SkData.  This will
     *  attempt to reuse existing encoded data (as returned by refEncoded).
     *
     *  We defer to the SkPixelSerializer both for vetting existing encoded data
     *  (useEncodedData) and for encoding the image (encode) when no such data is
     *  present or is rejected by the serializer.
     *
     *  If not specified, we use a default serializer which 1) always accepts existing data
     *  (in any format) and 2) encodes to PNG.
     *
     *  If no compatible encoded data exists and encoding fails, this method will also
     *  fail (return NULL).
     */
    SkData* encode(SkPixelSerializer* = nullptr) const;

    /**
     *  If the image already has its contents in encoded form (e.g. PNG or JPEG), return a ref
     *  to that data (which the caller must call unref() on). The caller is responsible for calling
     *  unref on the data when they are done.
     *
     *  If the image does not already has its contents in encoded form, return NULL.
     *
     *  Note: to force the image to return its contents as encoded data, try calling encode(...).
     */
    SkData* refEncoded() const;

    const char* toString(SkString*) const;

    /**
     *  Return a new image that is a subset of this image. The underlying implementation may
     *  share the pixels, or it may make a copy.
     *
     *  If subset does not intersect the bounds of this image, or the copy/share cannot be made,
     *  NULL will be returned.
     */
    sk_sp<SkImage> makeSubset(const SkIRect& subset) const;

    /**
     *  Ensures that an image is backed by a texture (when GrContext is non-null), suitable for use
     *  with surfaces that have the supplied destination color space. If no transformation is
     *  required, the returned image may be the same as this image. If this image is from a
     *  different GrContext, this will fail.
     */
    sk_sp<SkImage> makeTextureImage(GrContext*, SkColorSpace* dstColorSpace) const;

    /**
     *  Constructs a texture backed image from data that was previously uploaded on another thread
     *  and GrContext. The GrContext used to upload the data must be in the same GL share group as
     *  the one passed in here, or otherwise be able to share resources with the passed in context.
     */
    static sk_sp<SkImage> MakeFromCrossContextImageData(GrContext*,
                                                        std::unique_ptr<SkCrossContextImageData>);

    /**
     * If the image is texture-backed this will make a raster copy of it (or nullptr if reading back
     * the pixels fails). Otherwise, it returns the original image.
     */
    sk_sp<SkImage> makeNonTextureImage() const;
    /**
     *  Apply a given image filter to this image, and return the filtered result.
     *
     *  The subset represents the active portion of this image. The return value is similarly an
     *  SkImage, with an active subset (outSubset). This is usually used with texture-backed
     *  images, where the texture may be approx-match and thus larger than the required size.
     *
     *  clipBounds constrains the device-space extent of the image which may be produced to the
     *  given rect.
     *
     *  offset is the amount to translate the resulting image relative to the src when it is drawn.
     *  This is an out-param.
     *
     *  If the result image cannot be created, or the result would be transparent black, null
     *  is returned, in which case the offset and outSubset parameters should be ignored by the
     *  caller.
     */
    sk_sp<SkImage> makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
                                  const SkIRect& clipBounds, SkIRect* outSubset,
                                  SkIPoint* offset) const;

    /** Drawing params for which a deferred texture image data should be optimized. */
    struct DeferredTextureImageUsageParams {
        DeferredTextureImageUsageParams(const SkMatrix matrix, const SkFilterQuality quality,
                                        int preScaleMipLevel)
            : fMatrix(matrix), fQuality(quality), fPreScaleMipLevel(preScaleMipLevel) {}
        SkMatrix        fMatrix;
        SkFilterQuality fQuality;
        int             fPreScaleMipLevel;
    };

    /**
     * This method allows clients to capture the data necessary to turn a SkImage into a texture-
     * backed image. If the original image is codec-backed this will decode into a format optimized
     * for the context represented by the proxy. This method is thread safe with respect to the
     * GrContext whence the proxy came. Clients allocate and manage the storage of the deferred
     * texture data and control its lifetime. No cleanup is required, thus it is safe to simply free
     * the memory out from under the data.
     *
     * The same method is used both for getting the size necessary for pre-uploaded texture data
     * and for retrieving the data. The params array represents the set of draws over which to
     * optimize the pre-upload data.
     *
     * When called with a null buffer this returns the size that the client must allocate in order
     * to create deferred texture data for this image (or zero if this is an inappropriate
     * candidate). The buffer allocated by the client should be 8 byte aligned.
     *
     * When buffer is not null this fills in the deferred texture data for this image in the
     * provided buffer (assuming this is an appropriate candidate image and the buffer is
     * appropriately aligned). Upon success the size written is returned, otherwise 0.
     *
     * dstColorSpace is the color space of the surface where this texture will ultimately be used.
     * If the method determines that mip-maps are needed, this helps determine the correct strategy
     * for building them (gamma-correct or not).
     */
    size_t getDeferredTextureImageData(const GrContextThreadSafeProxy&,
                                       const DeferredTextureImageUsageParams[],
                                       int paramCnt,
                                       void* buffer,
                                       SkColorSpace* dstColorSpace = nullptr) const;

    /**
     * Returns a texture-backed image from data produced in SkImage::getDeferredTextureImageData.
     * The context must be the context that provided the proxy passed to
     * getDeferredTextureImageData.
     */
    static sk_sp<SkImage> MakeFromDeferredTextureImageData(GrContext*, const void*, SkBudgeted);

    // Helper functions to convert to SkBitmap

    enum LegacyBitmapMode {
        kRO_LegacyBitmapMode,
        kRW_LegacyBitmapMode,
    };

    /**
     *  Attempt to create a bitmap with the same pixels as the image. The result will always be
     *  a raster-backed bitmap (texture-backed bitmaps are DEPRECATED, and not supported here).
     *
     *  If the mode is kRO (read-only), the resulting bitmap will be marked as immutable.
     *
     *  On succcess, returns true. On failure, returns false and the bitmap parameter will be reset
     *  to empty.
     */
    bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;

    /**
     *  Returns true if the image is backed by an image-generator or other src that creates
     *  (and caches) its pixels / texture on-demand.
     */
    bool isLazyGenerated() const;

    /**
     *  If |target| is supported, returns an SkImage in the |target| color space.
     *  Otherwise, returns nullptr.
     *
     *  This will leave the image as is if it already in the |target| color space.
     *  Otherwise, it will convert the pixels from the src color space to the |target|
     *  color space.  If this->colorSpace() is nullptr, the src color space will be
     *  treated as sRGB.
     *
     *  If |premulBehavior| is kIgnore, any premultiplication or unpremultiplication will
     *  be performed in the gamma encoded space.  If it is kRespect, premultiplication is
     *  assumed to be linear.
     */
    sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target,
                                  SkTransferFunctionBehavior premulBehavior) const;

protected:
    SkImage(int width, int height, uint32_t uniqueID);

private:
    static sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&,
                                                const GrMipLevel* texels, int mipLevelCount,
                                                SkBudgeted, SkDestinationSurfaceColorMode);

    const int       fWidth;
    const int       fHeight;
    const uint32_t  fUniqueID;

    typedef SkRefCnt INHERITED;
};

#endif
