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 "SkColor.h"
12#include "SkImageInfo.h"
13
14class SkBitmap;
15class SkData;
16class SkImageGenerator;
17
18/**
19 *  Takes ownership of SkImageGenerator.  If this method fails for
20 *  whatever reason, it will return false and immediatetely delete
21 *  the generator.  If it succeeds, it will modify destination
22 *  bitmap.
23 *
24 *  If generator is NULL, will safely return false.
25 *
26 *  If this fails or when the SkDiscardablePixelRef that is
27 *  installed into destination is destroyed, it will call
28 *  SkDELETE() on the generator.  Therefore, generator should be
29 *  allocated with SkNEW() or SkNEW_ARGS().
30 *
31 *  @param destination Upon success, this bitmap will be
32 *  configured and have a pixelref installed.
33 *
34 *  @return true iff successful.
35 */
36SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination);
37
38
39/**
40 *  An interface that allows a purgeable PixelRef (such as a
41 *  SkDiscardablePixelRef) to decode and re-decode an image as needed.
42 */
43class SK_API SkImageGenerator {
44public:
45    /**
46     *  The PixelRef which takes ownership of this SkImageGenerator
47     *  will call the image generator's destructor.
48     */
49    virtual ~SkImageGenerator() { }
50
51#ifdef SK_SUPPORT_LEGACY_IMAGEGENERATORAPI
52    virtual SkData* refEncodedData() { return this->onRefEncodedData(); }
53    virtual bool getInfo(SkImageInfo* info) { return this->onGetInfo(info); }
54    virtual bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
55        return this->onGetPixels(info, pixels, rowBytes, NULL, NULL);
56    }
57#else
58    /**
59     *  Return a ref to the encoded (i.e. compressed) representation,
60     *  of this data.
61     *
62     *  If non-NULL is returned, the caller is responsible for calling
63     *  unref() on the data when it is finished.
64     */
65    SkData* refEncodedData() { return this->onRefEncodedData(); }
66
67    /**
68     *  Return some information about the image, allowing the owner of
69     *  this object to allocate pixels.
70     *
71     *  Repeated calls to this function should give the same results,
72     *  allowing the PixelRef to be immutable.
73     *
74     *  @return false if anything goes wrong.
75     */
76    bool getInfo(SkImageInfo* info);
77
78    /**
79     *  Decode into the given pixels, a block of memory of size at
80     *  least (info.fHeight - 1) * rowBytes + (info.fWidth *
81     *  bytesPerPixel)
82     *
83     *  Repeated calls to this function should give the same results,
84     *  allowing the PixelRef to be immutable.
85     *
86     *  @param info A description of the format (config, size)
87     *         expected by the caller.  This can simply be identical
88     *         to the info returned by getInfo().
89     *
90     *         This contract also allows the caller to specify
91     *         different output-configs, which the implementation can
92     *         decide to support or not.
93     *
94     *  If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
95     *  SkPMColor values in ctable. On success the generator must copy N colors into that storage,
96     *  (where N is the logical number of table entries) and set ctableCount to N.
97     *
98     *  If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
99     *  is not null, it will be set to 0.
100     *
101     *  @return false if anything goes wrong or if the image info is
102     *          unsupported.
103     */
104    bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
105                   SkPMColor ctable[], int* ctableCount);
106
107    /**
108     *  Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType.
109     */
110    bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
111#endif
112
113    /**
114     *  If planes or rowBytes is NULL or if any entry in planes is NULL or if any entry in rowBytes
115     *  is 0, this imagegenerator should output the sizes and return true if it can efficiently
116     *  return YUV planar data. If it cannot, it should return false. Note that either planes and
117     *  rowBytes are both fully defined and non NULL/non 0 or they are both NULL or have NULL or 0
118     *  entries only. Having only partial planes/rowBytes information is not supported.
119     *
120     *  If all planes and rowBytes entries are non NULL or non 0, then it should copy the
121     *  associated YUV data into those planes of memory supplied by the caller. It should validate
122     *  that the sizes match what it expected. If the sizes do not match, it should return false.
123     */
124    bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
125                       SkYUVColorSpace* colorSpace);
126
127protected:
128    virtual SkData* onRefEncodedData();
129    virtual bool onGetInfo(SkImageInfo* info);
130    virtual bool onGetPixels(const SkImageInfo& info,
131                             void* pixels, size_t rowBytes,
132                             SkPMColor ctable[], int* ctableCount);
133    virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
134    virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
135                                 SkYUVColorSpace* colorSpace);
136};
137
138#endif  // SkImageGenerator_DEFINED
139