Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2013 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 SkImageGenerator_DEFINED
      9 #define SkImageGenerator_DEFINED
     10 
     11 #include "SkBitmap.h"
     12 #include "SkColor.h"
     13 #include "SkImage.h"
     14 #include "SkImageInfo.h"
     15 #include "SkYUVSizeInfo.h"
     16 
     17 class GrContext;
     18 class GrContextThreadSafeProxy;
     19 class GrTextureProxy;
     20 class GrSamplerParams;
     21 class SkBitmap;
     22 class SkData;
     23 class SkMatrix;
     24 class SkPaint;
     25 class SkPicture;
     26 
     27 class SK_API SkImageGenerator : public SkNoncopyable {
     28 public:
     29     /**
     30      *  The PixelRef which takes ownership of this SkImageGenerator
     31      *  will call the image generator's destructor.
     32      */
     33     virtual ~SkImageGenerator() { }
     34 
     35     uint32_t uniqueID() const { return fUniqueID; }
     36 
     37     /**
     38      *  Return a ref to the encoded (i.e. compressed) representation,
     39      *  of this data. If the GrContext is non-null, then the caller is only interested in
     40      *  gpu-specific formats, so the impl may return null even if they have encoded data,
     41      *  assuming they know it is not suitable for the gpu.
     42      *
     43      *  If non-NULL is returned, the caller is responsible for calling
     44      *  unref() on the data when it is finished.
     45      */
     46     SkData* refEncodedData(GrContext* ctx = nullptr) {
     47         return this->onRefEncodedData(ctx);
     48     }
     49 
     50     /**
     51      *  Return the ImageInfo associated with this generator.
     52      */
     53     const SkImageInfo& getInfo() const { return fInfo; }
     54 
     55     /**
     56      *  Decode into the given pixels, a block of memory of size at
     57      *  least (info.fHeight - 1) * rowBytes + (info.fWidth *
     58      *  bytesPerPixel)
     59      *
     60      *  Repeated calls to this function should give the same results,
     61      *  allowing the PixelRef to be immutable.
     62      *
     63      *  @param info A description of the format (config, size)
     64      *         expected by the caller.  This can simply be identical
     65      *         to the info returned by getInfo().
     66      *
     67      *         This contract also allows the caller to specify
     68      *         different output-configs, which the implementation can
     69      *         decide to support or not.
     70      *
     71      *         A size that does not match getInfo() implies a request
     72      *         to scale. If the generator cannot perform this scale,
     73      *         it will return kInvalidScale.
     74      *
     75      *  If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
     76      *  SkPMColor values in ctable. On success the generator must copy N colors into that storage,
     77      *  (where N is the logical number of table entries) and set ctableCount to N.
     78      *
     79      *  If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
     80      *  is not null, it will be set to 0.
     81      *
     82      *  @return true on success.
     83      */
     84     bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
     85                    SkPMColor ctable[], int* ctableCount);
     86 
     87     /**
     88      *  Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
     89      *  uses the default Options.
     90      */
     91     bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
     92 
     93     /**
     94      *  If decoding to YUV is supported, this returns true.  Otherwise, this
     95      *  returns false and does not modify any of the parameters.
     96      *
     97      *  @param sizeInfo   Output parameter indicating the sizes and required
     98      *                    allocation widths of the Y, U, and V planes.
     99      *  @param colorSpace Output parameter.
    100      */
    101     bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const;
    102 
    103     /**
    104      *  Returns true on success and false on failure.
    105      *  This always attempts to perform a full decode.  If the client only
    106      *  wants size, it should call queryYUV8().
    107      *
    108      *  @param sizeInfo   Needs to exactly match the values returned by the
    109      *                    query, except the WidthBytes may be larger than the
    110      *                    recommendation (but not smaller).
    111      *  @param planes     Memory for each of the Y, U, and V planes.
    112      */
    113     bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]);
    114 
    115 #if SK_SUPPORT_GPU
    116     /**
    117      *  If the generator can natively/efficiently return its pixels as a GPU image (backed by a
    118      *  texture) this will return that image. If not, this will return NULL.
    119      *
    120      *  This routine also supports retrieving only a subset of the pixels. That subset is specified
    121      *  by the following rectangle:
    122      *
    123      *      subset = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height())
    124      *
    125      *  If subset is not contained inside the generator's bounds, this returns false.
    126      *
    127      *      whole = SkIRect::MakeWH(getInfo().width(), getInfo().height())
    128      *      if (!whole.contains(subset)) {
    129      *          return false;
    130      *      }
    131      *
    132      *  Regarding the GrContext parameter:
    133      *
    134      *  It must be non-NULL. The generator should only succeed if:
    135      *  - its internal context is the same
    136      *  - it can somehow convert its texture into one that is valid for the provided context.
    137      */
    138     sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info,
    139                                           const SkIPoint& origin);
    140 #endif
    141 
    142     /**
    143      *  If the default image decoder system can interpret the specified (encoded) data, then
    144      *  this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
    145      *  the caller is still responsible for managing their ownership of the data.
    146      */
    147     static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>);
    148 
    149     /** Return a new image generator backed by the specified picture.  If the size is empty or
    150      *  the picture is NULL, this returns NULL.
    151      *  The optional matrix and paint arguments are passed to drawPicture() at rasterization
    152      *  time.
    153      */
    154     static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>,
    155                                                              const SkMatrix*, const SkPaint*,
    156                                                              SkImage::BitDepth,
    157                                                              sk_sp<SkColorSpace>);
    158 
    159     bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo& info, SkBitmap::Allocator* allocator);
    160 
    161 protected:
    162     enum {
    163         kNeedNewImageUniqueID = 0
    164     };
    165 
    166     SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
    167 
    168     virtual SkData* onRefEncodedData(GrContext* ctx);
    169 
    170     virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
    171                              SkPMColor ctable[], int* ctableCount);
    172 
    173     virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
    174         return false;
    175     }
    176     virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) {
    177         return false;
    178     }
    179 
    180 #if SK_SUPPORT_GPU
    181     virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
    182                                                     const SkIPoint&);
    183 #endif
    184 
    185 private:
    186     const SkImageInfo fInfo;
    187     const uint32_t fUniqueID;
    188 
    189     // This is our default impl, which may be different on different platforms.
    190     // It is called from NewFromEncoded() after it has checked for any runtime factory.
    191     // The SkData will never be NULL, as that will have been checked by NewFromEncoded.
    192     static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
    193 };
    194 
    195 #endif  // SkImageGenerator_DEFINED
    196