Line data Source code
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 0 : virtual ~SkImageGenerator() { }
34 :
35 0 : 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 0 : SkData* refEncodedData(GrContext* ctx = nullptr) {
47 0 : return this->onRefEncodedData(ctx);
48 : }
49 :
50 : /**
51 : * Return the ImageInfo associated with this generator.
52 : */
53 0 : 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 : protected:
160 : enum {
161 : kNeedNewImageUniqueID = 0
162 : };
163 :
164 : SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
165 :
166 : virtual SkData* onRefEncodedData(GrContext* ctx);
167 :
168 : virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
169 : SkPMColor ctable[], int* ctableCount);
170 :
171 0 : virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
172 0 : return false;
173 : }
174 0 : virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) {
175 0 : return false;
176 : }
177 :
178 : struct Options {
179 0 : Options()
180 0 : : fColorTable(nullptr)
181 : , fColorTableCount(nullptr)
182 0 : , fBehavior(SkTransferFunctionBehavior::kRespect)
183 0 : {}
184 :
185 : SkPMColor* fColorTable;
186 : int* fColorTableCount;
187 : SkTransferFunctionBehavior fBehavior;
188 : };
189 : bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* opts);
190 0 : virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
191 : const Options& opts) {
192 0 : return this->onGetPixels(info, pixels, rowBytes, opts.fColorTable, opts.fColorTableCount);
193 : }
194 :
195 : #if SK_SUPPORT_GPU
196 : virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
197 : const SkIPoint&);
198 : #endif
199 :
200 : private:
201 : const SkImageInfo fInfo;
202 : const uint32_t fUniqueID;
203 :
204 : friend class SkImageCacherator;
205 :
206 : // This is our default impl, which may be different on different platforms.
207 : // It is called from NewFromEncoded() after it has checked for any runtime factory.
208 : // The SkData will never be NULL, as that will have been checked by NewFromEncoded.
209 : static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
210 : };
211 :
212 : #endif // SkImageGenerator_DEFINED
|